
<!DOCTYPE html>
<html lang="">


<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
  <meta name="theme-color" content="#202020"/>
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <script src="/js/busuanzi.pure.mini.js" async></script>
  
  
    <meta name="keywords" content="Java,Spring,SpringFramework," />
  

  
    <meta name="description" content="一个专注一coding的网站。提供丰富编程知识，包括Spring、Java、EmberJS、SpringBoot等等技术。" />
  
  
  <link rel="icon" type="image/x-icon" href="/image/favicon.ico">
  <title>Spring IoC原理 [ Keep Coding ]</title>
  
    <!-- stylesheets list from config.yml -->
    
      <link rel="stylesheet" href="/css/pure-min.css">
    
      <link rel="stylesheet" href="/css/xoxo.css">
    
  
<meta name="generator" content="Hexo 5.0.2"><link rel="alternate" href="/atom.xml" title="Keep Coding" type="application/atom+xml">
</head>

<body>
  <div class="nav-container">
    <nav class="home-menu pure-menu pure-menu-horizontal">
  <a class="pure-menu-heading" href="/">
    <img class="avatar" src="/image/favicon.ico">
    <span class="title">Keep Coding</span>
  </a>

  <ul class="pure-menu-list clearfix">
      
          
            <li class="pure-menu-item"><a href="/" class="pure-menu-link">首页</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/archives" class="pure-menu-link">归档</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/tags" class="pure-menu-link">标签</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/search" class="pure-menu-link">搜索</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/about" class="pure-menu-link">关于</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/atom.xml" class="pure-menu-link">订阅</a></li>
          
      
  </ul>
   
</nav>
  </div>

  <div class="container" id="content-outer">
    <div class="inner" id="content-inner">
      <div class="post-container">
  <article class="post" id="post">
    <header class="post-header text-center">
      <h1 class="title">
        Spring IoC原理
      </h1>
      <span>
        
        <time class="time" datetime="2020-10-18T16:16:49.330Z">
        2020-10-19
      </time>
        
      </span>
      <span class="slash">/</span>
      <span class="post-meta">
      <span class="post-tags">
        <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java/" rel="tag">Java</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Spring/" rel="tag">Spring</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/SpringFramework/" rel="tag">SpringFramework</a></li></ul>
      </span>
    </span>
      <span class="slash">/</span>
      <span class="read">
      <span id="busuanzi_value_page_pv"></span> 点击
    </span>
      <span class="slash">/</span>
      <span class="read">阅读耗时 104 分钟</span>
    </header>

    <div class="post-content">
      <blockquote>
<p>注意：本篇的源码使用Spring5.0以上版本。</p>
</blockquote>
<h2 id="BeanDefinition对象"><a href="#BeanDefinition对象" class="headerlink" title="BeanDefinition对象"></a>BeanDefinition对象</h2><p>Bean定义主要对象包括如下几个属性：</p>
<table>
<thead>
<tr>
<th>Property</th>
<th align="right">描述</th>
</tr>
</thead>
<tbody><tr>
<td>Class</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-class">bean实例</a></td>
</tr>
<tr>
<td>Name</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-beanname">Bean名称</a></td>
</tr>
<tr>
<td>Scope</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes">Bean类型（单例、原型..)</a></td>
</tr>
<tr>
<td>构造函数参数</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-collaborators">Dependency Injection</a></td>
</tr>
<tr>
<td>Properties</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-collaborators">Dependency Injection</a></td>
</tr>
<tr>
<td>Autowirging mode</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-autowire">自动注入模型</a></td>
</tr>
<tr>
<td>Lazy initizlization</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-lazy-init">懒加载模型</a></td>
</tr>
<tr>
<td>Iniitialization method</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-lifecycle-initializingbean">初始化方法</a></td>
</tr>
<tr>
<td>Destruction method</td>
<td align="right"><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-lifecycle-disposablebean">销毁方法</a></td>
</tr>
</tbody></table>
<p>bean定义所有属性大概有上百个。就以最常用的<code>RootBeanDefinition</code>为例，这个类是bean定义最核心的实现类。类中定义非常多属性，这些属性都是bean的定义信息。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/** Map with String keys and Object values. */</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">final</span> Map&lt;String, Object&gt; attributes = <span class="keyword">new</span> LinkedHashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> Object source;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant for the default scope name: &#123;<span class="doctag">@code</span> &quot;&quot;&#125;, equivalent to singleton</span></span><br><span class="line"><span class="comment">     * status unless overridden from a parent bean definition (if applicable).</span></span><br><span class="line"><span class="comment">     * 默认bean作用域</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> String SCOPE_DEFAULT = <span class="string">&quot;&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates no external autowiring at all.</span></span><br><span class="line"><span class="comment">     * 自动注入模式</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setAutowireMode</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates autowiring bean properties by name.</span></span><br><span class="line"><span class="comment">     * 自动注入通过bean名字</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setAutowireMode</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates autowiring bean properties by type.</span></span><br><span class="line"><span class="comment">     * 自动注入通过bean类型</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setAutowireMode</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates autowiring a constructor.</span></span><br><span class="line"><span class="comment">     * 自动注入通过构造函数</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setAutowireMode</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates determining an appropriate autowire strategy</span></span><br><span class="line"><span class="comment">     * through introspection of the bean class.</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setAutowireMode</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@deprecated</span> as of Spring 3.0: If you are using mixed autowiring strategies,</span></span><br><span class="line"><span class="comment">     * use annotation-based autowiring for clearer demarcation of autowiring needs.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="meta">@Deprecated</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates no dependency check at all.</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setDependencyCheck</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> DEPENDENCY_CHECK_NONE = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates dependency checking for object references.</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setDependencyCheck</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> DEPENDENCY_CHECK_OBJECTS = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates dependency checking for &quot;simple&quot; properties.</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setDependencyCheck</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> org.springframework.beans.BeanUtils#isSimpleProperty</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> DEPENDENCY_CHECK_SIMPLE = <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates dependency checking for all properties</span></span><br><span class="line"><span class="comment">     * (object references as well as &quot;simple&quot; properties).</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #setDependencyCheck</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> DEPENDENCY_CHECK_ALL = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Constant that indicates the container should attempt to infer the</span></span><br><span class="line"><span class="comment">     * &#123;<span class="doctag">@link</span> #setDestroyMethodName destroy method name&#125; for a bean as opposed to</span></span><br><span class="line"><span class="comment">     * explicit specification of a method name. The value &#123;<span class="doctag">@value</span>&#125; is specifically</span></span><br><span class="line"><span class="comment">     * designed to include characters otherwise illegal in a method name, ensuring</span></span><br><span class="line"><span class="comment">     * no possibility of collisions with legitimately named methods having the same</span></span><br><span class="line"><span class="comment">     * name.</span></span><br><span class="line"><span class="comment">     * &lt;p&gt;Currently, the method names detected during destroy method inference</span></span><br><span class="line"><span class="comment">     * are &quot;close&quot; and &quot;shutdown&quot;, if present on the specific bean class.</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> String INFER_METHOD = <span class="string">&quot;(inferred)&quot;</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">volatile</span> Object beanClass;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> String scope = SCOPE_DEFAULT;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> abstractFlag = <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> Boolean lazyInit;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> autowireMode = AUTOWIRE_NO;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> dependencyCheck = DEPENDENCY_CHECK_NONE;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> String[] dependsOn;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> autowireCandidate = <span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> primary = <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">final</span> Map&lt;String, AutowireCandidateQualifier&gt; qualifiers = <span class="keyword">new</span> LinkedHashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> Supplier&lt;?&gt; instanceSupplier;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> nonPublicAccessAllowed = <span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> lenientConstructorResolution = <span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> String factoryBeanName;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> String factoryMethodName;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> ConstructorArgumentValues constructorArgumentValues;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> MutablePropertyValues propertyValues;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> MethodOverrides methodOverrides = <span class="keyword">new</span> MethodOverrides();</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> String initMethodName;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> String destroyMethodName;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> enforceInitMethod = <span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> enforceDestroyMethod = <span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> synthetic = <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> role = BeanDefinition.ROLE_APPLICATION;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> String description;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> Resource resource;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> BeanDefinitionHolder decoratedDefinition;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> AnnotatedElement qualifiedElement;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Determines if the definition needs to be re-merged. */</span></span><br><span class="line"><span class="keyword">volatile</span> <span class="keyword">boolean</span> stale;</span><br><span class="line"></span><br><span class="line"><span class="keyword">boolean</span> allowCaching = <span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">boolean</span> isFactoryMethodUnique = <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">volatile</span> ResolvableType targetType;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field for caching the determined Class of a given bean definition. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">volatile</span> Class&lt;?&gt; resolvedTargetType;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field for caching if the bean is a factory bean. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">volatile</span> Boolean isFactoryBean;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field for caching the return type of a generically typed factory method. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">volatile</span> ResolvableType factoryMethodReturnType;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field for caching a unique factory method candidate for introspection. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">volatile</span> Method factoryMethodToIntrospect;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Common lock for the four constructor fields below. */</span></span><br><span class="line"><span class="keyword">final</span> Object constructorArgumentLock = <span class="keyword">new</span> Object();</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field for caching the resolved constructor or factory method. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line">Executable resolvedConstructorOrFactoryMethod;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field that marks the constructor arguments as resolved. */</span></span><br><span class="line"><span class="keyword">boolean</span> constructorArgumentsResolved = <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field for caching fully resolved constructor arguments. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line">Object[] resolvedConstructorArguments;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field for caching partly prepared constructor arguments. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line">Object[] preparedConstructorArguments;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Common lock for the two post-processing fields below. */</span></span><br><span class="line"><span class="keyword">final</span> Object postProcessingLock = <span class="keyword">new</span> Object();</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field that indicates MergedBeanDefinitionPostProcessor having been applied. */</span></span><br><span class="line"><span class="keyword">boolean</span> postProcessed = <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Package-visible field that indicates a before-instantiation post-processor having kicked in. */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">volatile</span> Boolean beforeInstantiationResolved;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> Set&lt;Member&gt; externallyManagedConfigMembers;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> Set&lt;String&gt; externallyManagedInitMethods;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="keyword">private</span> Set&lt;String&gt; externallyManagedDestroyMethods;</span><br></pre></td></tr></table></figure>



<h2 id="Spring中Bean生命周期"><a href="#Spring中Bean生命周期" class="headerlink" title="Spring中Bean生命周期"></a>Spring中Bean生命周期</h2><p><img src="/Users/ubuntuvim/code/xcoding/source/_posts/Spring/up-ee3f05213d700d84185d441cd3add81063f.png" alt="Spring中Bean生命周期"></p>
<p>这个图还缺少一个后置处理器，在最上面应该还有一个<code>BeanDefinitionRegistryPostProcess</code>，这个后置处理器在<code>BeanFactoryPostProcessor</code>之前执行。</p>
<h2 id="Spring-IoC体系结构"><a href="#Spring-IoC体系结构" class="headerlink" title="Spring IoC体系结构"></a>Spring IoC体系结构</h2><h3 id="BeanFactory"><a href="#BeanFactory" class="headerlink" title="BeanFactory"></a>BeanFactory</h3><p>Spring Bean的创建是典型的工厂模式，这一系列的Bean工厂也就是IoC容器为开发者管理对象间的依赖关系提供了很多的便利和基础服务，在Spring中有许多的实现提供用户选择和使用。最核心的类结构如下：</p>
<pre class="mermaid">graph BT

ListableBeanFactory --> BeanFactory
ConfigurableListableBeanFactory --> ListableBeanFactory
DefaultListableBeanFactory -.-> ConfigurableListableBeanFactory

HierarchicalBeanFactory --> BeanFactory
ConfigurableBeanFactory --> HierarchicalBeanFactory
ConfigurableListableBeanFactory --> ConfigurableBeanFactory

AutowireCapableBeanFactory --> BeanFactory
ConfigurableListableBeanFactory --> AutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory -.-> ConfigurableBeanFactory
DefaultListableBeanFactory --> AbstractAutowireCapableBeanFactory</pre>

<p>其中<code>BeanFactory</code>作为顶层的接口，它定义了IoC容器的基本功能实现，比如<code>getBean()</code>方法就是这个接口定义的。<br>它有三个子类（或者是实现类），它们是：<code>ListableBeanFactory</code>、<code>HierarchicalBeanFactory</code>和<code>AutowireCapableBeanFactory</code>。但是从上图可以看到最终的默认实现类是<code>DefaultListableBeanFactory</code>。它实现了所有的接口，这样做的目的是什么呢？<br>查阅相关的资料可以发现，这些几个接口的实现都是有特定的使用场景的，它们主要是在Spring内部操作对象的传递和转换的过程中，对对象的数据访问所做的限制。比如<code>ListableBeanFactory</code>接口表示这些bean是可列表的；<code>HierarchicalBeanFactory</code>表示这些bean是有继承关系的，也就是说这些bean是可能有父类bean；<code>AutowireCapableBeanFactory</code>接口定义了bean的自动装配规则。这四个接口共同定义了Bean的集合，Bean之间的关系，Bean的行为，从而组成了IoC容器的基本结构。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">BeanFactory</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 对FactoryBean的转义定义，如果使用beanName获取到的是FactoryBean接口中getObject()方法返回的实例</span></span><br><span class="line"><span class="comment">     * 如果要拿到FactoryBean本身则需要加上&amp;前缀，applicationContext.getBean(&amp;beanName)</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    String FACTORY_BEAN_PREFIX = <span class="string">&quot;&amp;&quot;</span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据beanName获取容器中实例化好的bean</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function">Object <span class="title">getBean</span><span class="params">(String name)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据bean的名字和Class类型来得到bean实例，增加了类型安全验证机制。</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    &lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(String name, Class&lt;T&gt; requiredType)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取bean实例时可以传递构造方法的参数，args就是构造方法的参数。</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function">Object <span class="title">getBean</span><span class="params">(String name, Object... args)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据bean的类型获取bean实例。比如getBean(User.class)</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    &lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(Class&lt;T&gt; requiredType)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据bean的类型和构造函数的参数获取bean实例。比如getBean(User.class, age, name)</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    &lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(Class&lt;T&gt; requiredType, Object... args)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取一个提供器类型的bean，通常是Spring框架内部使用。</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    &lt;T&gt; <span class="function">ObjectProvider&lt;T&gt; <span class="title">getBeanProvider</span><span class="params">(Class&lt;T&gt; requiredType)</span></span>;</span><br><span class="line"></span><br><span class="line">    &lt;T&gt; <span class="function">ObjectProvider&lt;T&gt; <span class="title">getBeanProvider</span><span class="params">(ResolvableType requiredType)</span></span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 提供对bean的检索，看看是否在IOC容器有这个名字的bean</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">boolean</span> <span class="title">containsBean</span><span class="params">(String name)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">boolean</span> <span class="title">isSingleton</span><span class="params">(String name)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">boolean</span> <span class="title">isPrototype</span><span class="params">(String name)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">boolean</span> <span class="title">isTypeMatch</span><span class="params">(String name, Class&lt;?&gt; typeToMatch)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException</span>;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 得到bean实例的Class类型</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Nullable</span></span><br><span class="line">    Class&lt;?&gt; getType(String name) <span class="keyword">throws</span> NoSuchBeanDefinitionException;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Nullable</span></span><br><span class="line">    Class&lt;?&gt; getType(String name, <span class="keyword">boolean</span> allowFactoryBeanInit) <span class="keyword">throws</span> NoSuchBeanDefinitionException;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 得到bean的别名，如果根据别名检索，那么其原名也会被检索出来    </span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    String[] getAliases(String name);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>FactoryBean</code>只定义了IoC容器的基本行为，它并不关心bean是如何定义，怎么加载的。<br>而具体是定义和加载是在其他的实现类中处理的，比如<code>XmlBeanFactory</code>、<code>ClasspathXmlApplicationContext</code>等。<br><code>XmlBeanFactory</code>是容器的最基本实现（<em>但是目前这个类已经声明为过时</em>），其他的加载类都是在此基础上的扩展。</p>
<h4 id="BeanDefinition（bean定义信息，IoC核心数据结构）"><a href="#BeanDefinition（bean定义信息，IoC核心数据结构）" class="headerlink" title="BeanDefinition（bean定义信息，IoC核心数据结构）"></a>BeanDefinition（bean定义信息，IoC核心数据结构）</h4><p>Spring容器管理了我们定义的各种bean对象及其相互关系，bean在对象实现是以<code>BeanDefinition</code>类描述的。</p>
<pre class="mermaid">graph BT

AttributeAccessorSupport -.-> AttributeAccessor
BeanMatadataAttributeAccessor --> AttributeAccessorSupport
BeanMatadataAttributeAccessor -.-> BeanMatadataElement
AbstractBeanDefinition --> BeanMatadataAttributeAccessor
RootBeanDefinition --> AbstractBeanDefinition
GenericBeanDefinition --> AbstractBeanDefinition
ChildBeanDefinition --> AbstractBeanDefinition

BeanDefinition --> AttributeAccessor
BeanDefinition --> BeanMatadataElement
AbstractBeanDefinition -.-> BeanDefinition</pre>

<p>Bean的解析过程非常复杂，功能被分的很细，因为这里需要被扩展的地方非常多，也提供了很多接口给开发者用于修改bean的定义。保证了足够的灵活性，以应对变化。Bean的解析主要是对Spring配置文件或者配置类的解析，解析过程如下：</p>
<pre class="mermaid">graph BT
XmlBeanDefinitionReader --> AbstractBeanDefinitionReader
AbstractBeanDefinitionReader -.-> BeanDefinitionReader

XmlBeanDefinitionReader -.-> DefaultBeanDefinitionDocumentReader
DefaultBeanDefinitionDocumentReader -.-> BeanDefinitionDocumentReader

XmlBeanDefinitionReader -.-> BeanDefinitionDocumentReader</pre>



<h2 id="IoC-容器初始化、bean实例化（核心内容）"><a href="#IoC-容器初始化、bean实例化（核心内容）" class="headerlink" title="IoC 容器初始化、bean实例化（核心内容）"></a>IoC 容器初始化、bean实例化（核心内容）</h2><p>IoC容器的初始化包括<code>BeanDefinition</code>的<code>Resource</code>定位、载入和注册三个基本过程。我们以<code>ApplicationContext</code>为例，这个类是我们最常见也是最常用的。</p>
<p>主要类关系如下：</p>
<pre class="mermaid">graph BT

FileSystemXmlApplicationContext --> AbstractXmlApplicationContext
ClassPathXmlApplicationContext --> AbstractXmlApplicationContext
AbstractXmlApplicationContext --> AbstractRefreshableConfigApplicationContext
AbstractRefreshableConfigApplicationContext --> AbstractRefreshableApplicationContext
AbstractRefreshableApplicationContext --> AbstractApplicationContext
AbstractApplicationContext --> DefaultResourceLoader
DefaultResourceLoader -.-> ResourceLoader
AbstractApplicationContext -.-> ConfigurableApplicationContext
ConfigurableApplicationContext --> ApplicationContext
ApplicationContext --> ListableBeanFactory

XmlWebApplication --> AbstractRefreshableWebApplicationContext
AbstractRefreshableWebApplicationContext --> AbstractRefreshableConfigApplicationContext
AbstractRefreshableWebApplicationContext -.-> ConfigurableWebApplicationContext
ConfigurableWebApplicationContext --> ConfigurableApplicationContext
ConfigurableWebApplicationContext --> WebApplicationContext
WebApplicationContext --> ApplicationContext
ApplicationContext --> HierarchicalBeanFactory

AnnotactionConfigApplicationContext --> GenericApplicationContext 
AnnotactionConfigApplicationContext -.-> AnnotationConfigRegistry
GenericApplicationContext --> AbstractApplicationContext
GenericApplicationContext -.-> BeanDefinitionRegistry</pre>

<p><code>ApplicationContext</code>运行上下文嵌套，通过保持父上下文可以维持一个上下文体系。对于bean的查找可以在这个上下文体系中发生，首先检查当前上下文，其次是父上下文，逐级向上，这样为不同的Spring应用提供了一个共享的bean定义环境。</p>
<p>主要有三种方式可以使用容器：<code>ClassPathXmlApplicationContext</code>、<code>FileSystemXmlApplicationContext</code>、<code>AnnotactionConfigApplicationContext</code>、<code>XmlWebApplicationContext</code>，其中第三种是最常用的，也是使用最广泛、最简单的。对于3.0之前更多是使用的xml配置方式，但是现在使用最多的是基于注解的方式，特别是springboot，全部都是基于注解做到零配置。<code>XmlWebApplicationContext</code>基本都是在SpringMVC的项目中使用。</p>
<blockquote>
<p>以<code>FileSystemXmlApplicationContext</code>为例讲解IoC容器从读取xml -&gt; 解析xml配置信息 -&gt; 转换成BeanDefinition -&gt; 初始化bean对象 -&gt; 设置bean属性（依赖） -&gt; bean销毁 整个bean生命周期过程。</p>
</blockquote>
<h3 id="bean定义资源准备（设置xml配置文件路径、设置资源加载器）"><a href="#bean定义资源准备（设置xml配置文件路径、设置资源加载器）" class="headerlink" title="bean定义资源准备（设置xml配置文件路径、设置资源加载器）"></a>bean定义资源准备（设置xml配置文件路径、设置资源加载器）</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FileSystemXmlApplicationContext</span> <span class="keyword">extends</span> <span class="title">AbstractXmlApplicationContext</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(ApplicationContext parent)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(parent);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(String configLocation)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>(<span class="keyword">new</span> String[] &#123;configLocation&#125;, <span class="keyword">true</span>, <span class="keyword">null</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(String... configLocations)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>(configLocations, <span class="keyword">true</span>, <span class="keyword">null</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(String[] configLocations, ApplicationContext parent)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>(configLocations, <span class="keyword">true</span>, parent);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(String[] configLocations, <span class="keyword">boolean</span> refresh)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>(configLocations, refresh, <span class="keyword">null</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">            String[] configLocations, <span class="keyword">boolean</span> refresh, <span class="meta">@Nullable</span> ApplicationContext parent)</span></span></span><br><span class="line"><span class="function">            <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="comment">// 创建资源加载器</span></span><br><span class="line">        <span class="keyword">super</span>(parent);</span><br><span class="line">        setConfigLocations(configLocations);</span><br><span class="line">        <span class="keyword">if</span> (refresh) &#123;</span><br><span class="line">            refresh();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  <span class="comment">// 这个方法会在解析xml的子类AbstractBeanDefinitionReader中回调</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> Resource <span class="title">getResourceByPath</span><span class="params">(String path)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (path.startsWith(<span class="string">&quot;/&quot;</span>)) &#123;</span><br><span class="line">            path = path.substring(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> FileSystemResource(path);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个类提供了非常多的扩展，可以使用不同类型的构造函数来创建容器。但是都最终会调用到这个构造方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">            String[] configLocations, <span class="keyword">boolean</span> refresh, <span class="meta">@Nullable</span> ApplicationContext parent)</span></span></span><br><span class="line"><span class="function">            <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">super</span>(parent);</span><br><span class="line">        setConfigLocations(configLocations);</span><br><span class="line">        <span class="keyword">if</span> (refresh) &#123;</span><br><span class="line">            refresh();</span><br><span class="line">        &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个构造方法在执行的时候首先执行父类<code>AbstractXmlApplicationContext</code>的构造方法，父类构造方法会先设置bean资源加载器。然后再调用父类的<code>setConfigLocations(configLoacations)</code>方法，这个方法用于设置bean定义资源文件（xml文件）的路径。通过类层架追踪，xml资源的加载最终是在<code>FileSystemXmlApplicationContext</code>的父类再网上几层的父类<code>AbstractXmlApplicationContext</code>中实现的。</p>
<pre class="mermaid">graph BT

FileSystemXmlApplicationContext -->|super方法| AbstractXmlApplicationContext
AbstractXmlApplicationContext -->|super方法| AbstractRefreshableConfigApplicationContext
AbstractRefreshableConfigApplicationContext -->|super方法| AbstractRefreshableApplicationContext
AbstractRefreshableApplicationContext -->|super方法| AbstractApplicationContext
AbstractApplicationContext --> |this| AbstractApplicationContext
AbstractApplicationContext --> getResourcePatternResolver获取资源加载器</pre>

<p><code>AbstractApplicationContext</code>的资源加载过程如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// FileSystemXmlApplicationContext不断的通过super()方法找到父类的父类的父类。。。</span></span><br><span class="line"><span class="comment">// 最终到达它真正的实现地方</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">AbstractApplicationContext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 获取资源处理器（读取spring配置文件）</span></span><br><span class="line">  <span class="keyword">this</span>.resourcePatternResolver = getResourcePatternResolver();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> ResourcePatternResolver <span class="title">getResourcePatternResolver</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 因为AbstractApplicationContext继承了DefaultResourceLoader</span></span><br><span class="line">  <span class="comment">// DefaultResourceLoader实现了ResourceLoader接口，所以可以直接传this进去</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> PathMatchingResourcePatternResolver(<span class="keyword">this</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>资源加载器初始化完成之后，开始设置资源路径。<code>setConfigLocations(configLocations);</code>这个方法也是调用父类<code>AbstractRefreshableConfigApplicationContext</code>的方法完成的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setConfigLocations</span><span class="params">(<span class="meta">@Nullable</span> String... locations)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (locations != <span class="keyword">null</span>) &#123;</span><br><span class="line">            Assert.noNullElements(locations, <span class="string">&quot;Config locations must not be null&quot;</span>);</span><br><span class="line">            <span class="keyword">this</span>.configLocations = <span class="keyword">new</span> String[locations.length];</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; locations.length; i++) &#123;</span><br><span class="line">                <span class="keyword">this</span>.configLocations[i] = resolvePath(locations[i]).trim();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">this</span>.configLocations = <span class="keyword">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>这个方法执行完毕之后，我们需要加载的bean资源文件都转成一个<code>String</code>数组，保存到变量<code>configLocations</code>中。</p>
<p>资源加载器准备好之后就是开始加载解析bean配置，然后根据bean定义执行各种操作，包括定义解析、bean初始化等等。</p>
<h3 id="加载、解析、转换XML定义，实例化bean"><a href="#加载、解析、转换XML定义，实例化bean" class="headerlink" title="加载、解析、转换XML定义，实例化bean"></a>加载、解析、转换XML定义，实例化bean</h3><p>Spring IoC容器对bean定义的加载是从<code>refresh()</code>方法开始的，这个方法是一个模板方法，它的作用是：在创建IoC容器前，如果已经有容器则把容器销毁关闭，然后再重新创建一个新的容器，然后再对容器做初始化。<code>FileSystemXmlApplicationContext</code>通过调用父类的<code>AbstractApplicationContext.refresh()</code>方法实现容器的创建，加载，初始等一系列操作。回到这个类的构造方法，可以看到在构造方法内部调用了<code>refresh()</code>方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">FileSystemXmlApplicationContext</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">            String[] configLocations, <span class="keyword">boolean</span> refresh, <span class="meta">@Nullable</span> ApplicationContext parent)</span></span></span><br><span class="line"><span class="function">            <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="comment">// 通过类层级，一直通过super()方法一层层往上找父类的父类的父类。。。。</span></span><br><span class="line">        <span class="comment">// 最终找到AbstractApplicationContext的构造方法，</span></span><br><span class="line">        <span class="keyword">super</span>(parent);</span><br><span class="line">        setConfigLocations(configLocations);</span><br><span class="line">        <span class="keyword">if</span> (refresh) &#123;</span><br><span class="line">            refresh();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>通过类层级往上找，他的父类<code>AbstractXmlApplicationContext</code>、<code>AbstractRefreshableConfigApplicationContext</code>、<code>AbstractRefreshableApplicationContext</code>都没有重写<code>refresh()</code>方法，这个方法的实现是在<code>AbstractApplicationContet</code>中实现的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">refresh</span><span class="params">()</span> <span class="keyword">throws</span> BeansException, IllegalStateException </span>&#123;</span><br><span class="line">        <span class="keyword">synchronized</span> (<span class="keyword">this</span>.startupShutdownMonitor) &#123;</span><br><span class="line">            <span class="comment">// Prepare this context for refreshing.</span></span><br><span class="line">            <span class="comment">// 准备此上下文以进行刷新。</span></span><br><span class="line">            prepareRefresh();</span><br><span class="line"></span><br><span class="line">            <span class="comment">// Tell the subclass to refresh the internal bean factory.</span></span><br><span class="line">            <span class="comment">// 获取beanFactory实例</span></span><br><span class="line">            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();</span><br><span class="line"></span><br><span class="line">            <span class="comment">// Prepare the bean factory for use in this context.</span></span><br><span class="line">            <span class="comment">// 准备上下文使用的BeanFactory</span></span><br><span class="line">            prepareBeanFactory(beanFactory);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="comment">// Allows post-processing of the bean factory in context subclasses.</span></span><br><span class="line">                <span class="comment">// 允许子类处理BeanFactory后置处理器</span></span><br><span class="line">                postProcessBeanFactory(beanFactory);</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Invoke factory processors registered as beans in the context.</span></span><br><span class="line">                <span class="comment">// 转到ConfigurationClassPostProcessor里面执行</span></span><br><span class="line">                <span class="comment">// 执行bean工厂的后置处理器，里面会有非常多的，非常复杂的BeanFactoryPostProcessor实现类的执行。</span></span><br><span class="line">                invokeBeanFactoryPostProcessors(beanFactory);</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Register bean processors that intercept bean creation.</span></span><br><span class="line">                <span class="comment">// 转到PostProcessorRegistrationDelegate</span></span><br><span class="line">                <span class="comment">// 注册bean工厂的后置处理器（仅仅是把Spring内部定义的和用户定义的BeanPostProcessor注册到容器中，后面的步骤才会真正执行），</span></span><br><span class="line">                <span class="comment">// 这些后置处理器在bean的构造方法执行之后，在执行init方法前后执行指定的逻辑</span></span><br><span class="line">                registerBeanPostProcessors(beanFactory);</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Initialize message source for this context.</span></span><br><span class="line">                <span class="comment">// 初始化上下文的消息资源，比如message-xxx.properties</span></span><br><span class="line">                initMessageSource();</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Initialize event multicaster for this context.</span></span><br><span class="line">                <span class="comment">// 初始化上下文多波器</span></span><br><span class="line">                initApplicationEventMulticaster();</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Initialize other special beans in specific context subclasses.</span></span><br><span class="line">                <span class="comment">// 在上下文中初始化其他的bean，子类实现</span></span><br><span class="line">                onRefresh();</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Check for listener beans and register them.</span></span><br><span class="line">                <span class="comment">// 检查并注册监听器</span></span><br><span class="line">                registerListeners();</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Instantiate all remaining (non-lazy-init) singletons.</span></span><br><span class="line">                <span class="comment">// 初始化剩下其他的单例bean，包括FactoryBean，（用户定义的大部分类都是在这里实例化的）</span></span><br><span class="line">                <span class="comment">// 非常非常重要的方法，是整个IOC容器核心部分</span></span><br><span class="line">                finishBeanFactoryInitialization(beanFactory);</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Last step: publish corresponding event.</span></span><br><span class="line">                <span class="comment">// 初始化上下文生命周期处理器，发布事件</span></span><br><span class="line">                finishRefresh();</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">                <span class="keyword">if</span> (logger.isWarnEnabled()) &#123;</span><br><span class="line">                    logger.warn(<span class="string">&quot;Exception encountered during context initialization - &quot;</span> +</span><br><span class="line">                            <span class="string">&quot;cancelling refresh attempt: &quot;</span> + ex);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Destroy already created singletons to avoid dangling resources.</span></span><br><span class="line">                destroyBeans();</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Reset &#x27;active&#x27; flag.</span></span><br><span class="line">                cancelRefresh(ex);</span><br><span class="line"></span><br><span class="line">                <span class="comment">// Propagate exception to caller.</span></span><br><span class="line">                <span class="keyword">throw</span> ex;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">finally</span> &#123;</span><br><span class="line">                <span class="comment">// Reset common introspection caches in Spring&#x27;s core, since we</span></span><br><span class="line">                <span class="comment">// might not ever need metadata for singleton beans anymore...</span></span><br><span class="line">                resetCommonCaches();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p><code>refresh()</code>方法的主要作用为了IoC容器bean的生命周期管理提供条件，Spring IoC容器载入bean定义资源文件从其子类<code>refreshBeanFactory()</code>方法启动。在创建IoC容器前，如果已经存在则把已经创建的容器销毁关闭，以保障<code>refresh()</code>之后是新建的、单例的容器。</p>
<p>这个方法就是Spring最最最核心的实现，整个Spring最核心的特性也是在这个方法实现的，包括后置处理器、事件发布、bean加载、<code>@Component @Autowired</code>等等注解、AOP等，下面逐个方法解析学习。</p>
<h3 id="prepareRefresh"><a href="#prepareRefresh" class="headerlink" title="prepareRefresh()"></a><code>prepareRefresh()</code></h3><p>这个方法比较简单，就是为容器的创建做准备，标记容器的状态（激活状态为true，关闭状态为false），打印容器开始启动的时间。</p>
<h3 id="obtainFreshBeanFactory"><a href="#obtainFreshBeanFactory" class="headerlink" title="obtainFreshBeanFactory();"></a><code>obtainFreshBeanFactory();</code></h3><p>这个方法为容器的做了非常多的工作，设置bean定义的资源加载器，加载bean定义为<code>BeanDefinition</code>对象，并保存到容器的缓存中（保存在<code>ConfigurableListableBeanFactory</code>实例的Map成员属性中）。当然这一步仅仅是加载把定义信息转换成容器所需要的数据结构，并未做bean的实例化。目前的bean还没开始创建呢，还是在内存中的一些定义信息。</p>
<p><code>AbstractApplicationContext</code>的<code>obtainFreshBeanFactory()</code>方法调用子类容器的<code>refreshBaenFactory()</code>方法，启动容器载入bean定义资源文件。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> ConfigurableListableBeanFactory <span class="title">obtainFreshBeanFactory</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 调用子类AbstractRefreshableApplicationContext.refreshBeanFactory()方法</span></span><br><span class="line">  <span class="comment">// 此方法由子类实现，使用委派设计模式，父类定义了抽象refreshBeanFactory方法，具体实现调用子类的方法。</span></span><br><span class="line">  refreshBeanFactory();  </span><br><span class="line">  <span class="keyword">return</span> getBeanFactory();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="创建容器、加载bean定义信息"><a href="#创建容器、加载bean定义信息" class="headerlink" title="创建容器、加载bean定义信息"></a>创建容器、加载bean定义信息</h4><p>通过调用<code>AbstractRefreshableApplicationContext.refreshBeanFactory()</code>创建一个新的容器（主要是创建了<code>DefaultListableBeanFactory</code>实例对象，准备好用于保存bean定义的缓存Map，然后加载bean定义到Map中（非常复杂的步骤）。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * This implementation performs an actual refresh of this context&#x27;s underlying</span></span><br><span class="line"><span class="comment">     * bean factory, shutting down the previous bean factory (if any) and</span></span><br><span class="line"><span class="comment">     * initializing a fresh bean factory for the next phase of the context&#x27;s lifecycle.</span></span><br><span class="line"><span class="comment">     * 实现上下文刷新，如果已经有bean fatory则先关闭，再重新初始化一个bean factory。</span></span><br><span class="line"><span class="comment">     * 此方法会在AbstractApplicationContext的refresh()方法中被调用</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title">refreshBeanFactory</span><span class="params">()</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        <span class="comment">// 先判断是否已经存在BeanFactory，如果当前线程已经初始化过了，则先销毁重新创建一个</span></span><br><span class="line">        <span class="keyword">if</span> (hasBeanFactory()) &#123;</span><br><span class="line">            destroyBeans();</span><br><span class="line">            closeBeanFactory();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            DefaultListableBeanFactory beanFactory = createBeanFactory();</span><br><span class="line">            beanFactory.setSerializationId(getId());</span><br><span class="line">            <span class="comment">// 容器定制化，设置启动参数、开启注解自动装配等等。</span></span><br><span class="line">            customizeBeanFactory(beanFactory);</span><br><span class="line">            <span class="comment">// 加载bean定义，非常重要的一个方法</span></span><br><span class="line">            <span class="comment">// 由子类AbstractXmlApplicationContext实现加载bean定义</span></span><br><span class="line">            <span class="comment">// 使用委派模式，父类定义抽象，具体实现由子类实现</span></span><br><span class="line">            loadBeanDefinitions(beanFactory);</span><br><span class="line">            <span class="keyword">synchronized</span> (<span class="keyword">this</span>.beanFactoryMonitor) &#123;</span><br><span class="line">                <span class="keyword">this</span>.beanFactory = beanFactory;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">catch</span> (IOException ex) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> ApplicationContextException(<span class="string">&quot;I/O error parsing bean definition source for &quot;</span> + getDisplayName(), ex);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h5 id="加载bean定义"><a href="#加载bean定义" class="headerlink" title="加载bean定义"></a>加载bean定义</h5><p><code>AbstractXmlApplicationContext.loadBeanDefinitions(beanFactory)</code>方法在一级子类<code>AbstractRefreshableApplicationContext</code>并没有实现，也是声明为<code>abstract</code>方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">loadBeanDefinitions</span><span class="params">(DefaultListableBeanFactory beanFactory)</span> <span class="keyword">throws</span> BeansException, IOException</span>;</span><br></pre></td></tr></table></figure>

<p>在他的二级子类<code>AbstractRefreshableConfigApplicationContext</code>也没有实现，而是在它的三级级子类<code>AbstractXmlApplicationContext</code>才实现。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Loads the bean definitions via an XmlBeanDefinitionReader.</span></span><br><span class="line"><span class="comment">     * 通过XmlBeanDefinitionReader加载所有的bean定义，</span></span><br><span class="line"><span class="comment">     * 此方法在AbstractApplicationContext中定义了抽象，由子类实现。</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> org.springframework.beans.factory.xml.XmlBeanDefinitionReader</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #initBeanDefinitionReader</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #loadBeanDefinitions</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">loadBeanDefinitions</span><span class="params">(DefaultListableBeanFactory beanFactory)</span> <span class="keyword">throws</span> BeansException, IOException </span>&#123;</span><br><span class="line">  <span class="comment">// Create a new XmlBeanDefinitionReader for the given BeanFactory.</span></span><br><span class="line">  <span class="comment">// 创建bean定义读取器，通过回调设置到容器中，不同的子类设置不同的读取器（有些是读取xml配置，有的是读取java代码的bean定义）</span></span><br><span class="line">  XmlBeanDefinitionReader beanDefinitionReader = <span class="keyword">new</span> XmlBeanDefinitionReader(beanFactory);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Configure the bean definition reader with this context&#x27;s</span></span><br><span class="line">  <span class="comment">// resource loading environment.</span></span><br><span class="line">  <span class="comment">// 加载上下文的环境配置，配置bean定义</span></span><br><span class="line">  beanDefinitionReader.setEnvironment(<span class="keyword">this</span>.getEnvironment());</span><br><span class="line">  <span class="comment">// 设置资源加载器，</span></span><br><span class="line">  <span class="comment">// 因为本类的最上层父类DefaultResourceLoader也继承了DefaultResourceLoader，所以可以直接传this。</span></span><br><span class="line">  beanDefinitionReader.setResourceLoader(<span class="keyword">this</span>);</span><br><span class="line">  beanDefinitionReader.setEntityResolver(<span class="keyword">new</span> ResourceEntityResolver(<span class="keyword">this</span>));</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Allow a subclass to provide custom initialization of the reader,</span></span><br><span class="line">  <span class="comment">// then proceed with actually loading the bean definitions.</span></span><br><span class="line">  <span class="comment">// 允许子类提供自定义的初始化读取器reader，然后处理加载bean定义</span></span><br><span class="line">  initBeanDefinitionReader(beanDefinitionReader);</span><br><span class="line">  <span class="comment">// 加载bean定义</span></span><br><span class="line">  loadBeanDefinitions(beanDefinitionReader);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="1-AbstractXmlApplicationContext-loadBeanDefinitions-beanDefinitionReader"><a href="#1-AbstractXmlApplicationContext-loadBeanDefinitions-beanDefinitionReader" class="headerlink" title="1. AbstractXmlApplicationContext.loadBeanDefinitions(beanDefinitionReader)"></a>1. AbstractXmlApplicationContext.loadBeanDefinitions(beanDefinitionReader)</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">loadBeanDefinitions</span><span class="params">(XmlBeanDefinitionReader reader)</span> <span class="keyword">throws</span> BeansException, IOException </span>&#123;</span><br><span class="line">  <span class="comment">// 获取到工厂开始加载之前就设置的配置文件路径，</span></span><br><span class="line">  <span class="comment">// ApplicationContext applicationContext = new ClassPathXmlApplicationContext(&quot;spring-env-test.xml&quot;);</span></span><br><span class="line">  <span class="comment">// 由子类实现bean定义资源，子类实现getConfigResources()方法，比如ClassPathXmlApplicationContext的构造方法里就重写了setConfigLocations()</span></span><br><span class="line">  Resource[] configResources = getConfigResources();</span><br><span class="line">  <span class="keyword">if</span> (configResources != <span class="keyword">null</span>) &#123;</span><br><span class="line">    reader.loadBeanDefinitions(configResources);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 子类实现bean定义资源路径，子类实现getConfigLocations()方法</span></span><br><span class="line">  <span class="comment">// 如果资源定位configResources为空，则获取子类的路径资源，</span></span><br><span class="line">  <span class="comment">// 比如，子类FileSystemXmlApplicationContext构造方法中实现了getConfigLocations()方法，指定的文件路径。</span></span><br><span class="line">  String[] configLocations = getConfigLocations();</span><br><span class="line">  <span class="keyword">if</span> (configLocations != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="comment">// 调用AbstractBeanDefinitionReader.loadBeanDefinitions()方法</span></span><br><span class="line">    reader.loadBeanDefinitions(configLocations);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="2-AbstractBeanDefinitionReader-loadBeanDefinitions-方法"><a href="#2-AbstractBeanDefinitionReader-loadBeanDefinitions-方法" class="headerlink" title="2. AbstractBeanDefinitionReader.loadBeanDefinitions()方法"></a>2. AbstractBeanDefinitionReader.loadBeanDefinitions()方法</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">loadBeanDefinitions</span><span class="params">(String location, <span class="meta">@Nullable</span> Set&lt;Resource&gt; actualResources)</span> <span class="keyword">throws</span> BeanDefinitionStoreException </span>&#123;</span><br><span class="line">  <span class="comment">// 拿到实例化的资源读取器。在构造方法里面已经做了初始化</span></span><br><span class="line">  <span class="comment">// 初始化：this.resourceLoader = new PathMatchingResourcePatternResolver();</span></span><br><span class="line">  ResourceLoader resourceLoader = getResourceLoader();</span><br><span class="line">  <span class="keyword">if</span> (resourceLoader == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(</span><br><span class="line">      <span class="string">&quot;Cannot load bean definitions from location [&quot;</span> + location + <span class="string">&quot;]: no ResourceLoader available&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// resourceLoader就是PathMatchingResourcePatternResolve。</span></span><br><span class="line">  <span class="comment">// PathMatchingResourcePatternResolver实现了ResourcePatternResolver接口</span></span><br><span class="line">  <span class="keyword">if</span> (resourceLoader <span class="keyword">instanceof</span> ResourcePatternResolver) &#123;</span><br><span class="line">    <span class="comment">// Resource pattern matching available.</span></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// 把符合路径下配置封装成Resource</span></span><br><span class="line">      Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);</span><br><span class="line">      <span class="comment">// 加载bean定义比如ClassPathXmlApplicationContext中指定的classpath*:/application.xml</span></span><br><span class="line">      <span class="keyword">int</span> count = loadBeanDefinitions(resources);</span><br><span class="line">      <span class="keyword">if</span> (actualResources != <span class="keyword">null</span>) &#123;</span><br><span class="line">        Collections.addAll(actualResources, resources);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">        logger.trace(<span class="string">&quot;Loaded &quot;</span> + count + <span class="string">&quot; bean definitions from location pattern [&quot;</span> + location + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">catch</span> (IOException ex) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(</span><br><span class="line">        <span class="string">&quot;Could not resolve bean definition resource pattern [&quot;</span> + location + <span class="string">&quot;]&quot;</span>, ex);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// Can only load single resources by absolute URL.</span></span><br><span class="line">    <span class="comment">// 通过绝对路径加载单个配置文件，比如FileSystemXmlApplicationContext中指定的</span></span><br><span class="line">    Resource resource = resourceLoader.getResource(location);</span><br><span class="line">    <span class="comment">// 调用子类的XmlBeanDefinitionReader.loadBeanDefinitions(Resource)方法</span></span><br><span class="line">    <span class="keyword">int</span> count = loadBeanDefinitions(resource);</span><br><span class="line">    <span class="keyword">if</span> (actualResources != <span class="keyword">null</span>) &#123;</span><br><span class="line">      actualResources.add(resource);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;Loaded &quot;</span> + count + <span class="string">&quot; bean definitions from location [&quot;</span> + location + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="3-DefaultResourceLoader-resourceLoader-getResource-location"><a href="#3-DefaultResourceLoader-resourceLoader-getResource-location" class="headerlink" title="3. DefaultResourceLoader.resourceLoader.getResource(location)"></a>3. DefaultResourceLoader.resourceLoader.getResource(location)</h5><p>以<code>FileSystemXmlApplicationContext</code>为例，加载资源会跳转到<code>resourceLoader.getResource(location)</code>这行，进入后发现最终会交给<code>DefaultResourceLoader.getResource()</code>方法实现。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Resource <span class="title">getResource</span><span class="params">(String location)</span> </span>&#123;</span><br><span class="line">  Assert.notNull(location, <span class="string">&quot;Location must not be null&quot;</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 协议类的路径</span></span><br><span class="line">  <span class="keyword">for</span> (ProtocolResolver protocolResolver : getProtocolResolvers()) &#123;</span><br><span class="line">    Resource resource = protocolResolver.resolve(location, <span class="keyword">this</span>);</span><br><span class="line">    <span class="keyword">if</span> (resource != <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> resource;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 文件系统方式</span></span><br><span class="line">  <span class="keyword">if</span> (location.startsWith(<span class="string">&quot;/&quot;</span>)) &#123;</span><br><span class="line">    <span class="comment">// getResourceByPath也被子类FileSystemXmlApplicationContext重写了，</span></span><br><span class="line">    <span class="comment">// 如果是使用FileSystemXmlApplicationContext来初始化容器，则会回调子类重写的方法。返回FileSystemResource对象</span></span><br><span class="line">    <span class="keyword">return</span> getResourceByPath(location);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 类路径方式：classpath:*/application.xml</span></span><br><span class="line">  <span class="keyword">else</span> <span class="keyword">if</span> (location.startsWith(CLASSPATH_URL_PREFIX)) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// Try to parse the location as a URL...</span></span><br><span class="line">      URL url = <span class="keyword">new</span> URL(location);</span><br><span class="line">      <span class="keyword">return</span> (ResourceUtils.isFileURL(url) ? <span class="keyword">new</span> FileUrlResource(url) : <span class="keyword">new</span> UrlResource(url));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">catch</span> (MalformedURLException ex) &#123;</span><br><span class="line">      <span class="comment">// No URL -&gt; resolve as resource path.</span></span><br><span class="line">      <span class="keyword">return</span> getResourceByPath(location);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>判断是加载本地文件系统资源之后，进入到<code>getResource</code>第二种情况<code>startWitch(&quot;/&quot;)</code>，然后执行<code>getResourceByPath()</code>方法，此方法被<code>FileSystemApplicationContext</code>重写了，所以执行的时候是执行子类重写了的方法体，拿到一个<code>FileSystemResource</code>对象。</p>
<p>拿到资源之后，回到<code>AbstractBeanDefinitionReader.loadBeanDefinitions()</code>。调用<code>loadBeanDefinitions()</code>方法开始加载资源文件里面的bean定义信息。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">loadBeanDefinitions</span><span class="params">(EncodedResource encodedResource)</span> <span class="keyword">throws</span> BeanDefinitionStoreException </span>&#123;</span><br><span class="line">  <span class="comment">// 其他无关主题代码省略</span></span><br><span class="line">  </span><br><span class="line">  <span class="comment">// resourcesCurrentlyBeingLoaded是一个ThreadLocal，get()方法拿到的就是当前线程的资源</span></span><br><span class="line">  Set&lt;EncodedResource&gt; currentResources = <span class="keyword">this</span>.resourcesCurrentlyBeingLoaded.get();</span><br><span class="line">  <span class="keyword">if</span> (currentResources == <span class="keyword">null</span>) &#123;</span><br><span class="line">    currentResources = <span class="keyword">new</span> HashSet&lt;&gt;(<span class="number">4</span>);</span><br><span class="line">    <span class="keyword">this</span>.resourcesCurrentlyBeingLoaded.set(currentResources);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 把当前资源加入到currentResources中，如果已经存在add()方法返回false，说明此资源已经添加过，无需再次添加</span></span><br><span class="line">  <span class="comment">// 并提示开发者资源名称重复定义了。</span></span><br><span class="line">  <span class="keyword">if</span> (!currentResources.add(encodedResource)) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(</span><br><span class="line">      <span class="string">&quot;Detected cyclic loading of &quot;</span> + encodedResource + <span class="string">&quot; - check your import definitions!&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// 将xml定义文件转成IO流程</span></span><br><span class="line">    InputStream inputStream = encodedResource.getResource().getInputStream();</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      InputSource inputSource = <span class="keyword">new</span> InputSource(inputStream);</span><br><span class="line">      <span class="keyword">if</span> (encodedResource.getEncoding() != <span class="keyword">null</span>) &#123;</span><br><span class="line">        inputSource.setEncoding(encodedResource.getEncoding());</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="comment">// 真正实现加载bean定义的方法</span></span><br><span class="line">      <span class="keyword">return</span> doLoadBeanDefinitions(inputSource, encodedResource.getResource());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">finally</span> &#123;</span><br><span class="line">      inputStream.close();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (IOException ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(</span><br><span class="line">      <span class="string">&quot;IOException parsing XML document from &quot;</span> + encodedResource.getResource(), ex);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">finally</span> &#123;</span><br><span class="line">    <span class="comment">// 已经加载过的资源从加载列表中移除</span></span><br><span class="line">    currentResources.remove(encodedResource);</span><br><span class="line">    <span class="keyword">if</span> (currentResources.isEmpty()) &#123;</span><br><span class="line">      <span class="comment">// 已经加载完成的资源一定要从本地线程变量中删除，以防内存泄漏</span></span><br><span class="line">      <span class="keyword">this</span>.resourcesCurrentlyBeingLoaded.remove();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="4-AbstractBeanDefinitionReader-doLoadBeanDefinitions-inputSource-encodedResource-getResource"><a href="#4-AbstractBeanDefinitionReader-doLoadBeanDefinitions-inputSource-encodedResource-getResource" class="headerlink" title="4. AbstractBeanDefinitionReader.doLoadBeanDefinitions(inputSource, encodedResource.getResource())"></a>4. AbstractBeanDefinitionReader.doLoadBeanDefinitions(inputSource, encodedResource.getResource())</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Actually load bean definitions from the specified XML file.</span></span><br><span class="line"><span class="comment">     * 加载指定配置文件里的bean定义</span></span><br><span class="line"><span class="comment">     * 比如最简单的bean定义：&lt;bean id=&quot;testBean&quot; class=&quot;com.ubuntuvim.spring.TestBean&quot; /&gt;</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">int</span> <span class="title">doLoadBeanDefinitions</span><span class="params">(InputSource inputSource, Resource resource)</span></span></span><br><span class="line"><span class="function">            <span class="keyword">throws</span> BeanDefinitionStoreException </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">// 读取配置资源并封装成Docment对象</span></span><br><span class="line">            Document doc = doLoadDocument(inputSource, resource);</span><br><span class="line">            <span class="comment">// 根据Document加载bean定义，非常重要的方法。</span></span><br><span class="line">            <span class="keyword">int</span> count = registerBeanDefinitions(doc, resource);</span><br><span class="line">            <span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">                logger.debug(<span class="string">&quot;Loaded &quot;</span> + count + <span class="string">&quot; bean definitions from &quot;</span> + resource);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> count;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 其他无关主题代码省略</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>通过<code>doLoadDocument()</code>方法将文件转成<code>document</code>对象，然后解析里面的内容，再根据内容做处理（处理过程非常复杂，根据bean定义的各种属性进行不同的操作。</p>
<h5 id="5-创建一个document解析工厂"><a href="#5-创建一个document解析工厂" class="headerlink" title="5. 创建一个document解析工厂"></a>5. 创建一个document解析工厂</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Document <span class="title">loadDocument</span><span class="params">(InputSource inputSource, EntityResolver entityResolver,</span></span></span><br><span class="line"><span class="function"><span class="params">                             ErrorHandler errorHandler, <span class="keyword">int</span> validationMode, <span class="keyword">boolean</span> namespaceAware)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 根据校验模式、命名解析创建解析工厂</span></span><br><span class="line">  DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);</span><br><span class="line">  <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">    logger.trace(<span class="string">&quot;Using JAXP provider [&quot;</span> + factory.getClass().getName() + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);</span><br><span class="line">  <span class="keyword">return</span> builder.parse(inputSource);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> DocumentBuilderFactory <span class="title">createDocumentBuilderFactory</span><span class="params">(<span class="keyword">int</span> validationMode, <span class="keyword">boolean</span> namespaceAware)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> ParserConfigurationException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建document解析工厂</span></span><br><span class="line">  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();</span><br><span class="line">  factory.setNamespaceAware(namespaceAware);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 设置工厂的属性</span></span><br><span class="line">  <span class="keyword">if</span> (validationMode != XmlValidationModeDetector.VALIDATION_NONE) &#123;</span><br><span class="line">    factory.setValidating(<span class="keyword">true</span>);</span><br><span class="line">    <span class="keyword">if</span> (validationMode == XmlValidationModeDetector.VALIDATION_XSD) &#123;</span><br><span class="line">      <span class="comment">// Enforce namespace aware for XSD...</span></span><br><span class="line">      factory.setNamespaceAware(<span class="keyword">true</span>);</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE, XSD_SCHEMA_LANGUAGE);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (IllegalArgumentException ex) &#123;</span><br><span class="line">        ParserConfigurationException pcex = <span class="keyword">new</span> ParserConfigurationException(</span><br><span class="line">          <span class="string">&quot;Unable to validate using XSD: Your JAXP provider [&quot;</span> + factory +</span><br><span class="line">          <span class="string">&quot;] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? &quot;</span> +</span><br><span class="line">          <span class="string">&quot;Upgrade to Apache Xerces (or Java 1.5) for full XSD support.&quot;</span>);</span><br><span class="line">        pcex.initCause(ex);</span><br><span class="line">        <span class="keyword">throw</span> pcex;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> factory;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>接着是根据Document对象解析里面的bean定义信息，这个解析过程非常复杂！！！！</p>
<p><code>XmlBeanDefinitionReader</code>类中的<code>doLoadBeanDefinitions()</code>方法是从指定路径的xml加载bean定义成document对象。然后调用<code>registerBeanDefinitions()</code>方法启动bean定义的解析。</p>
<h5 id="6-调用registerBeanDefinitions-方法启动bean定义解析"><a href="#6-调用registerBeanDefinitions-方法启动bean定义解析" class="headerlink" title="6. 调用registerBeanDefinitions()方法启动bean定义解析"></a>6. 调用<code>registerBeanDefinitions()</code>方法启动bean定义解析</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">registerBeanDefinitions</span><span class="params">(Document doc, Resource resource)</span> <span class="keyword">throws</span> BeanDefinitionStoreException </span>&#123;</span><br><span class="line">  <span class="comment">// 通过反射拿到DefaultBeanDefinitionDocumentReader</span></span><br><span class="line">  BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();</span><br><span class="line">  <span class="comment">// 获取解析之前的bean数量</span></span><br><span class="line">  <span class="keyword">int</span> countBefore = getRegistry().getBeanDefinitionCount();</span><br><span class="line">  documentReader.registerBeanDefinitions(doc, createReaderContext(resource));</span><br><span class="line">  <span class="comment">// bean总数 - 解析之前的数量，就是本次解析的bean数量</span></span><br><span class="line">  <span class="keyword">return</span> getRegistry().getBeanDefinitionCount() - countBefore;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> BeanDefinitionDocumentReader <span class="title">createBeanDefinitionDocumentReader</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// this.documentReaderClass = DefaultBeanDefinitionDocumentReader</span></span><br><span class="line">  <span class="keyword">return</span> BeanUtils.instantiateClass(<span class="keyword">this</span>.documentReaderClass);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="7-标签转换成BeanDefinition"><a href="#7-标签转换成BeanDefinition" class="headerlink" title="7.  标签转换成BeanDefinition"></a>7.  <bean>标签转换成BeanDefinition</h5><p>通过<code>BeanDefinitionDocumentReader.registerBeanDefinitions(doc, createReaderContext(resource))</code>把xml配置转换成容器内部的数据结构BeanDefinition对象。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ……省略其他代码</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 留给子类实现，在解析bean定义前做一些自定义的操作，可能用于后续框架的扩展</span></span><br><span class="line">preProcessXml(root);</span><br><span class="line"><span class="comment">// 解析bean定义，从&lt;beans&gt;开始解析所有子标签&lt;bean&gt;</span></span><br><span class="line">parseBeanDefinitions(root, <span class="keyword">this</span>.delegate);</span><br><span class="line"><span class="comment">// 留个子类实现，在解析完bean定义之后做一些自定义逻辑，可能用于后续框架的扩展</span></span><br><span class="line">postProcessXml(root);</span><br><span class="line"></span><br><span class="line"><span class="keyword">this</span>.delegate = parent;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ……省略其他代码</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Parse the elements at the root level in the document:</span></span><br><span class="line"><span class="comment">     * &quot;import&quot;, &quot;alias&quot;, &quot;bean&quot;.</span></span><br><span class="line"><span class="comment">     * 解析最顶层的元素，比如bean，import，alias标签</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> root the DOM root element of the document</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">parseBeanDefinitions</span><span class="params">(Element root, BeanDefinitionParserDelegate delegate)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (delegate.isDefaultNamespace(root)) &#123;</span><br><span class="line">    NodeList nl = root.getChildNodes();</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nl.getLength(); i++) &#123;</span><br><span class="line">      Node node = nl.item(i);</span><br><span class="line">      <span class="keyword">if</span> (node <span class="keyword">instanceof</span> Element) &#123;</span><br><span class="line">        Element ele = (Element) node;</span><br><span class="line">        <span class="keyword">if</span> (delegate.isDefaultNamespace(ele)) &#123;</span><br><span class="line">          <span class="comment">// 处理普通的子元素，比如&lt;bean&gt;、&lt;alise&gt;</span></span><br><span class="line">          parseDefaultElement(ele, delegate);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="comment">// 处理一些功能性配置，比如：&lt;context:component-scan /&gt;</span></span><br><span class="line">          <span class="comment">// &lt;aop:aspectj-autoproxy /&gt;</span></span><br><span class="line">          delegate.parseCustomElement(ele);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    delegate.parseCustomElement(root);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>parseDefaultElement(ele, delegate);</code>和<code>delegate.parseCustomElement(ele);</code>两个方法内部就是复杂而详细的解析过程。</p>
<p>包括<code>&lt;Import/&gt;</code>、<code>&lt;bean/&gt;</code>、<code>&lt;Alias</code>、<code>&lt;aop:aspectj-autoproxy /&gt;</code>等等标签的解析。详细代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">parseDefaultElement</span><span class="params">(Element ele, BeanDefinitionParserDelegate delegate)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 处理&lt;import&gt;标签，import标签用于导入其他的配置文件</span></span><br><span class="line">  <span class="keyword">if</span> (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) &#123;</span><br><span class="line">    importBeanDefinitionResource(ele);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 处理&lt;alias&gt;标签</span></span><br><span class="line">  <span class="keyword">else</span> <span class="keyword">if</span> (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) &#123;</span><br><span class="line">    processAliasRegistration(ele);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 处理&lt;bean&gt;标签，最重要的一个方法</span></span><br><span class="line">  <span class="keyword">else</span> <span class="keyword">if</span> (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) &#123;</span><br><span class="line">    processBeanDefinition(ele, delegate);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 处理&lt;beans&gt;标签，递归调用</span></span><br><span class="line">  <span class="keyword">else</span> <span class="keyword">if</span> (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) &#123;</span><br><span class="line">    <span class="comment">// recurse</span></span><br><span class="line">    doRegisterBeanDefinitions(ele);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">processBeanDefinition</span><span class="params">(Element ele, BeanDefinitionParserDelegate delegate)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 解析bean标签，解析完成后得到&lt;bean&gt;标签上面的属性信息，比如name、id、class等</span></span><br><span class="line">  BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);</span><br><span class="line">  <span class="keyword">if</span> (bdHolder != <span class="keyword">null</span>) &#123;</span><br><span class="line">    bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// Register the final decorated instance.</span></span><br><span class="line">      <span class="comment">// 解析完成后注册bean定义信息</span></span><br><span class="line">      <span class="comment">// 所谓的注册其实就是把bean定义信息put到工厂的beanDefinitionMap&lt;beanName, BeanDefinition&gt;中</span></span><br><span class="line">      BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">catch</span> (BeanDefinitionStoreException ex) &#123;</span><br><span class="line">      getReaderContext().error(<span class="string">&quot;Failed to register bean definition with name &#x27;&quot;</span> +</span><br><span class="line">                               bdHolder.getBeanName() + <span class="string">&quot;&#x27;&quot;</span>, ele, ex);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// Send registration event.</span></span><br><span class="line">    getReaderContext().fireComponentRegistered(<span class="keyword">new</span> BeanComponentDefinition(bdHolder));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ……其他方法的详细实现不展开说明。直接查看DefaultBeanDefinitionDocumentReader源码实现即可。</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>通过上述Spring容器对载入的bean定义Document解析可以看出，我们在使用配置文件时可以使用<code>&lt;Import&gt;</code>标签直接导入另外一个资源文件。使用<code>&lt;Alias&gt;</code>标签定义别名时，容器首先将别名元素定义注册到容器中。</p>
<p>如果是<code>&lt;beans&gt;</code>元素则递归调用，解析标签下的最原子定义。</p>
<p>如果是<code>&lt;bean&gt;</code>直接解析并转换成<code>BeanDefinition</code>对象put到容器缓存中。通过如下这2行代码实现的：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// xml定义转成容器的BeanDefinition</span></span><br><span class="line">BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);</span><br><span class="line"><span class="comment">// 把BeanDefinition保存到容器缓存Map中</span></span><br><span class="line">BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());</span><br></pre></td></tr></table></figure>

<p>xml转换成BeanDefinition。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> BeanDefinitionHolder <span class="title">parseBeanDefinitionElement</span><span class="params">(Element ele, <span class="meta">@Nullable</span> BeanDefinition containingBean)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 拿到&lt;bean&gt;定义的id属性值</span></span><br><span class="line">  String id = ele.getAttribute(ID_ATTRIBUTE);</span><br><span class="line">  <span class="comment">// 拿到&lt;bean&gt;定义的name属性值</span></span><br><span class="line">  String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);</span><br><span class="line"></span><br><span class="line">  List&lt;String&gt; aliases = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  <span class="comment">// 如果name属性定义别名，比如&lt;bean name=&quot;beanA, beanB, beanC&quot; class=&quot;com.ubuntuvim.service.impl.UserServiceImpl/&gt;</span></span><br><span class="line">  <span class="comment">// 直接把一个class定义成三个bean名，等价于如下三个定义：</span></span><br><span class="line">  <span class="comment">//  &lt;bean name=&quot;beanA&quot; class=&quot;com.ubuntuvim.service.impl.UserServiceImpl/&gt;</span></span><br><span class="line">  <span class="comment">//  &lt;bean name=&quot;beanB&quot; class=&quot;com.ubuntuvim.service.impl.UserServiceImpl/&gt;</span></span><br><span class="line">  <span class="comment">//  &lt;bean name=&quot;beanC&quot; class=&quot;com.ubuntuvim.service.impl.UserServiceImpl/&gt;</span></span><br><span class="line">  <span class="keyword">if</span> (StringUtils.hasLength(nameAttr)) &#123;</span><br><span class="line">    String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);</span><br><span class="line">    aliases.addAll(Arrays.asList(nameArr));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// beanName默认使用id属性的值，如果id属性为空，则获取name属性，如果name属性有多个值直接用第一个值作为beanName</span></span><br><span class="line">  String beanName = id;</span><br><span class="line">  <span class="keyword">if</span> (!StringUtils.hasText(beanName) &amp;&amp; !aliases.isEmpty()) &#123;</span><br><span class="line">    beanName = aliases.remove(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;No XML &#x27;id&#x27; specified - using &#x27;&quot;</span> + beanName +</span><br><span class="line">                   <span class="string">&quot;&#x27; as bean name and &quot;</span> + aliases + <span class="string">&quot; as aliases&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (containingBean == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="comment">// 校验&lt;beans&gt;标签下是否有重复的&lt;bean&gt;定义</span></span><br><span class="line">    checkNameUniqueness(beanName, aliases, ele);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 进一步解析bean的其他所有属性并统一封装至GenericBeanDefinition类型实例中</span></span><br><span class="line">  AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);</span><br><span class="line">  <span class="keyword">if</span> (beanDefinition != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (!StringUtils.hasText(beanName)) &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (containingBean != <span class="keyword">null</span>) &#123;</span><br><span class="line">          beanName = BeanDefinitionReaderUtils.generateBeanName(</span><br><span class="line">            beanDefinition, <span class="keyword">this</span>.readerContext.getRegistry(), <span class="keyword">true</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">          beanName = <span class="keyword">this</span>.readerContext.generateBeanName(beanDefinition);</span><br><span class="line">          <span class="comment">// Register an alias for the plain bean class name, if still possible,</span></span><br><span class="line">          <span class="comment">// if the generator returned the class name plus a suffix.</span></span><br><span class="line">          <span class="comment">// This is expected for Spring 1.2/2.0 backwards compatibility.</span></span><br><span class="line">          String beanClassName = beanDefinition.getBeanClassName();</span><br><span class="line">          <span class="keyword">if</span> (beanClassName != <span class="keyword">null</span> &amp;&amp;</span><br><span class="line">              beanName.startsWith(beanClassName) &amp;&amp; beanName.length() &gt; beanClassName.length() &amp;&amp;</span><br><span class="line">              !<span class="keyword">this</span>.readerContext.getRegistry().isBeanNameInUse(beanClassName)) &#123;</span><br><span class="line">            aliases.add(beanClassName);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">          logger.trace(<span class="string">&quot;Neither XML &#x27;id&#x27; nor &#x27;name&#x27; specified - &quot;</span> +</span><br><span class="line">                       <span class="string">&quot;using generated bean name [&quot;</span> + beanName + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (Exception ex) &#123;</span><br><span class="line">        error(ex.getMessage(), ele);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    String[] aliasesArray = StringUtils.toStringArray(aliases);</span><br><span class="line">    <span class="comment">// 所有属性解析、校验完成后封装成BeanDefinitionHolder实例并返回</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> AbstractBeanDefinition <span class="title">parseBeanDefinitionElement</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">  Element ele, String beanName, <span class="meta">@Nullable</span> BeanDefinition containingBean)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.parseState.push(<span class="keyword">new</span> BeanEntry(beanName));</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 解析class属性值</span></span><br><span class="line">  String className = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (ele.hasAttribute(CLASS_ATTRIBUTE)) &#123;</span><br><span class="line">    className = ele.getAttribute(CLASS_ATTRIBUTE).trim();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 解析parent属性值</span></span><br><span class="line">  String parent = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (ele.hasAttribute(PARENT_ATTRIBUTE)) &#123;</span><br><span class="line">    parent = ele.getAttribute(PARENT_ATTRIBUTE);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// 创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition</span></span><br><span class="line">    AbstractBeanDefinition bd = createBeanDefinition(className, parent);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 解析&lt;bean&gt;标签的扩展属性，比如singleton/scope/abstract/lazy-init/autowire等属性</span></span><br><span class="line">    parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);</span><br><span class="line">    <span class="comment">// 解析描述信息</span></span><br><span class="line">    bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));</span><br><span class="line"></span><br><span class="line">    parseMetaElements(ele, bd);</span><br><span class="line">    parseLookupOverrideSubElements(ele, bd.getMethodOverrides());</span><br><span class="line">    parseReplacedMethodSubElements(ele, bd.getMethodOverrides());</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 解析&lt;constructor-arg&gt;子元素</span></span><br><span class="line">    parseConstructorArgElements(ele, bd);</span><br><span class="line">    <span class="comment">// 解析&lt;property&gt;子元素</span></span><br><span class="line">    parsePropertyElements(ele, bd);</span><br><span class="line">    <span class="comment">// 解析&lt;qualifier&gt;子元素</span></span><br><span class="line">    parseQualifierElements(ele, bd);</span><br><span class="line"></span><br><span class="line">    bd.setResource(<span class="keyword">this</span>.readerContext.getResource());</span><br><span class="line">    bd.setSource(extractSource(ele));</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> bd;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (ClassNotFoundException ex) &#123;</span><br><span class="line">    error(<span class="string">&quot;Bean class [&quot;</span> + className + <span class="string">&quot;] not found&quot;</span>, ele, ex);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (NoClassDefFoundError err) &#123;</span><br><span class="line">    error(<span class="string">&quot;Class that bean class [&quot;</span> + className + <span class="string">&quot;] depends on not found&quot;</span>, ele, err);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    error(<span class="string">&quot;Unexpected failure during bean definition parsing&quot;</span>, ele, ex);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">finally</span> &#123;</span><br><span class="line">    <span class="keyword">this</span>.parseState.pop();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>所有bean相关定义信息解析完毕之后并不是直接就实例化成对象，目前仅仅只是解析成BeanDefinition对象，会在后面依赖注入的时候才从BeanDefinition缓存中拿出来实例化。</p>
<p>这些方法，每个展开都是一下详细实现细节。就补贴源码了。直接看Spring源码类<code>BeanDefinitionParserDelegate</code>即可。主要就是对<code>&lt;property&gt;</code>、<code>&lt;list&gt;</code>、<code>&lt;set&gt;</code>、<code>&lt;array&gt;</code>等等标签的解析。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 解析&lt;constructor-arg&gt;子元素</span></span><br><span class="line">parseConstructorArgElements(ele, bd);</span><br><span class="line"><span class="comment">// 解析&lt;property&gt;子元素</span></span><br><span class="line">parsePropertyElements(ele, bd);</span><br><span class="line"><span class="comment">// 解析&lt;qualifier&gt;子元素</span></span><br><span class="line">parseQualifierElements(ele, bd);</span><br></pre></td></tr></table></figure>

<h4 id="保存转换后的BeanDefinition到容器缓存中"><a href="#保存转换后的BeanDefinition到容器缓存中" class="headerlink" title="保存转换后的BeanDefinition到容器缓存中"></a>保存转换后的BeanDefinition到容器缓存中</h4><p>经过一系列的解析之后，得到容器需要的数据结构——BeanDefinition。然后通过<code>registerBeanDefinition()</code>方法设置到容器缓存中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">registerBeanDefinition</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">  BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> BeanDefinitionStoreException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Register bean definition under primary name.</span></span><br><span class="line">  <span class="comment">// 获取定义的bean名称</span></span><br><span class="line">  String beanName = definitionHolder.getBeanName();</span><br><span class="line">  <span class="comment">// 往容器中注册bean（就是put到容器缓存Map中），最终会保存在DefaultListableBeanFactory实例的一个Map成员属性上。</span></span><br><span class="line">  registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Register aliases for bean name, if any.</span></span><br><span class="line">  <span class="comment">// 如果有别名则注册bean的别名</span></span><br><span class="line">  String[] aliases = definitionHolder.getAliases();</span><br><span class="line">  <span class="keyword">if</span> (aliases != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">for</span> (String alias : aliases) &#123;</span><br><span class="line">      registry.registerAlias(beanName, alias);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>registerBeanDefinition()</code>方法的调用层级：</p>
<ul>
<li>BeanDefinitionRegistry  (org.springframework.beans.factory.support)  <ul>
<li>SimpleBeanDefinitionRegistry  (org.springframework.beans.factory.support)  <ul>
<li>DefaultListableBeanFactory  (org.springframework.beans.factory.support)</li>
</ul>
</li>
</ul>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">registerBeanDefinition</span><span class="params">(String beanName, BeanDefinition beanDefinition)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> BeanDefinitionStoreException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// ……其他无关代码省略</span></span><br><span class="line"></span><br><span class="line">  BeanDefinition existingDefinition = <span class="keyword">this</span>.beanDefinitionMap.get(beanName);</span><br><span class="line">  <span class="keyword">if</span> (existingDefinition != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="comment">// ……其他无关代码省略</span></span><br><span class="line">    <span class="keyword">this</span>.beanDefinitionMap.put(beanName, beanDefinition);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (hasBeanCreationStarted()) &#123;</span><br><span class="line">      <span class="comment">// Cannot modify startup-time collection elements anymore (for stable iteration)</span></span><br><span class="line">      <span class="keyword">synchronized</span> (<span class="keyword">this</span>.beanDefinitionMap) &#123;</span><br><span class="line">        <span class="keyword">this</span>.beanDefinitionMap.put(beanName, beanDefinition);</span><br><span class="line">        List&lt;String&gt; updatedDefinitions = <span class="keyword">new</span> ArrayList&lt;&gt;(<span class="keyword">this</span>.beanDefinitionNames.size() + <span class="number">1</span>);</span><br><span class="line">        updatedDefinitions.addAll(<span class="keyword">this</span>.beanDefinitionNames);</span><br><span class="line">        updatedDefinitions.add(beanName);</span><br><span class="line">        <span class="keyword">this</span>.beanDefinitionNames = updatedDefinitions;</span><br><span class="line">        removeManualSingletonName(beanName);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// Still in startup registration phase</span></span><br><span class="line">      <span class="keyword">this</span>.beanDefinitionMap.put(beanName, beanDefinition);</span><br><span class="line">      <span class="keyword">this</span>.beanDefinitionNames.add(beanName);</span><br><span class="line">      removeManualSingletonName(beanName);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">this</span>.frozenBeanDefinitionNames = <span class="keyword">null</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (existingDefinition != <span class="keyword">null</span> || containsSingleton(beanName)) &#123;</span><br><span class="line">    resetBeanDefinition(beanName);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>至此，bean定义资源文件被解析后，已经注册到容器中，被管理起来，完成了容器的初始化工作。回到我们一开始的<code>AbstractApplicationContext.refresh()</code>方法，现在只是完成了这个方法的<code>obtainFreshBeanFactory()</code>调用。不过已经完成IoC容器的创建并且读取加载了所有bean定义到容器中，这些信息已经是可以使用的信息，可以被get出来（当然get出来的也只是定义信息，或者说是bean的原材料）。后续容器的所有功能都是对这些bean定义信息的操作。这些bean定义信息就是IoC容器的控制反转的基础，真是有了这些信息，容器才能做到依赖注入，包括aop等。</p>
<p>真是万里长征第一步啊，不过是非常重要的第一步。</p>
<h3 id="prepareBeanFactory-beanFactory"><a href="#prepareBeanFactory-beanFactory" class="headerlink" title="prepareBeanFactory(beanFactory)"></a>prepareBeanFactory(beanFactory)</h3><p>这个方法比较简单，主要是进一步增强BeanFactory的功能。说白了就是往容器中set一些后续会使用的到功能类。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">prepareBeanFactory</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// Tell the internal bean factory to use the context&#x27;s class loader etc.</span></span><br><span class="line">  <span class="comment">// 设置类加载器，存在则直接设置（一般是ApplicationClassLoader)，不存在则创建一个新的默认加载器设置到容器中</span></span><br><span class="line">  <span class="comment">// 不存在会一直往上找，一直找到java根加载器BoostrapClassLoader</span></span><br><span class="line">  beanFactory.setBeanClassLoader(getClassLoader());</span><br><span class="line">  <span class="comment">// 设置EL表达式解析器</span></span><br><span class="line">  beanFactory.setBeanExpressionResolver(<span class="keyword">new</span> StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));</span><br><span class="line">  <span class="comment">// 设置属性注册解析器</span></span><br><span class="line">  beanFactory.addPropertyEditorRegistrar(<span class="keyword">new</span> ResourceEditorRegistrar(<span class="keyword">this</span>, getEnvironment()));</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理，</span></span><br><span class="line">  <span class="comment">// 从而在Aware接口实现类中的注入applicationContext</span></span><br><span class="line">  <span class="comment">// Configure the bean factory with context callbacks.</span></span><br><span class="line">  beanFactory.addBeanPostProcessor(<span class="keyword">new</span> ApplicationContextAwareProcessor(<span class="keyword">this</span>));</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 设置忽略的自动装配接口</span></span><br><span class="line">  beanFactory.ignoreDependencyInterface(EnvironmentAware.class);</span><br><span class="line">  beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);</span><br><span class="line">  beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);</span><br><span class="line">  beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);</span><br><span class="line">  beanFactory.ignoreDependencyInterface(MessageSourceAware.class);</span><br><span class="line">  beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 注册自动装配使用到的类</span></span><br><span class="line">  <span class="comment">// BeanFactory interface not registered as resolvable type in a plain factory.</span></span><br><span class="line">  <span class="comment">// MessageSource registered (and found for autowiring) as a bean.</span></span><br><span class="line">  beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);</span><br><span class="line">  beanFactory.registerResolvableDependency(ResourceLoader.class, <span class="keyword">this</span>);</span><br><span class="line">  beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, <span class="keyword">this</span>);</span><br><span class="line">  beanFactory.registerResolvableDependency(ApplicationContext.class, <span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 注册容器使用的监听器</span></span><br><span class="line">  <span class="comment">// Register early post-processor for detecting inner beans as ApplicationListeners.</span></span><br><span class="line">  beanFactory.addBeanPostProcessor(<span class="keyword">new</span> ApplicationListenerDetector(<span class="keyword">this</span>));</span><br><span class="line"></span><br><span class="line">  <span class="comment">//如果当前BeanFactory包含loadTimeWeaver Bean，说明存在类加载期织入AspectJ，</span></span><br><span class="line">  <span class="comment">// 则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理，</span></span><br><span class="line">  <span class="comment">// 从而实现类加载期织入AspectJ的目的。</span></span><br><span class="line">  <span class="comment">// Detect a LoadTimeWeaver and prepare for weaving, if found.</span></span><br><span class="line">  <span class="keyword">if</span> (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) &#123;</span><br><span class="line">    beanFactory.addBeanPostProcessor(<span class="keyword">new</span> LoadTimeWeaverAwareProcessor(beanFactory));</span><br><span class="line">    <span class="comment">// Set a temporary ClassLoader for type matching.</span></span><br><span class="line">    beanFactory.setTempClassLoader(<span class="keyword">new</span> ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//  注册当前容器环境environment组件Bean</span></span><br><span class="line">  <span class="comment">// Register default environment beans.</span></span><br><span class="line">  <span class="keyword">if</span> (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) &#123;</span><br><span class="line">    beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 注册当前电脑系统环境systemProperties组件Bean</span></span><br><span class="line">  <span class="keyword">if</span> (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) &#123;</span><br><span class="line">    beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 注册当前电脑系统的环境变量信息systemEnvironment</span></span><br><span class="line">  <span class="keyword">if</span> (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) &#123;</span><br><span class="line">    beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol>
<li>设置类加载器</li>
<li>设置EL表达式解析器（bean创建完成后填充属性使用比如@Value注解）、设置属性注册解析器</li>
<li>利用BeanPostProcessor特性给各种Aware接口实现类注入ApplicationContext中对象的属性？？</li>
<li>设置各种Aware接口实现类为忽略自自动装配</li>
<li>设置自动装配类，包括<code>BeanFactory</code>,<code>ResourceLoader</code>,<code>ApplicationEventPublisher</code>,<code>ApplicationContext</code></li>
<li>如果BeanFactory中存在loadTimeWeave的bean，则添加动态织入功能</li>
<li>注册各种可用组件（环境变量信息），比如<code>envrironment</code>,<code>systemProperties</code>,<code>systemEnvironment</code></li>
</ol>
<h3 id="postProcessBeanFactory-beanFactory"><a href="#postProcessBeanFactory-beanFactory" class="headerlink" title="postProcessBeanFactory(beanFactory)"></a>postProcessBeanFactory(beanFactory)</h3><p>这个方法是提供给子类定义一些后置处理器（也是往容器中set一些功能类）。比如子类<code>AbstractRefreshableWebApplicationContext</code>。这个是web项目中使用到初始化IoC容器的类，在容器启动之后增加了一些web项目用到的扩展。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">postProcessBeanFactory</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> </span>&#123;</span><br><span class="line">  beanFactory.addBeanPostProcessor(<span class="keyword">new</span> ServletContextAwareProcessor(<span class="keyword">this</span>.servletContext, <span class="keyword">this</span>.servletConfig));</span><br><span class="line">  beanFactory.ignoreDependencyInterface(ServletContextAware.class);</span><br><span class="line">  beanFactory.ignoreDependencyInterface(ServletConfigAware.class);</span><br><span class="line"></span><br><span class="line">  WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, <span class="keyword">this</span>.servletContext);</span><br><span class="line">  WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, <span class="keyword">this</span>.servletContext, <span class="keyword">this</span>.servletConfig);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="invokeBeanFactoryPostProcessors-beanFactory"><a href="#invokeBeanFactoryPostProcessors-beanFactory" class="headerlink" title="invokeBeanFactoryPostProcessors(beanFactory)"></a>invokeBeanFactoryPostProcessors(beanFactory)</h3><p>执行bean工厂的后置处理器，里面会有非常多的，非常复杂的BeanFactoryPostProcessor实现类的执行。</p>
<p>用于读取使用<code>@Component</code>、<code>@Service</code>等bean定义声明的类。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">invokeBeanFactoryPostProcessors</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 拿到当前应用上下文的BeanFactoryPostProcessor，</span></span><br><span class="line">  <span class="comment">// 1. 如果是使用FileSystemXmlApplicationContext启动容器默认情况getBeanFactoryPostProcessors()是空的。</span></span><br><span class="line">  <span class="comment">//         当用户手动调set方法注册BeanFactory后置处理器才有值，默认情况下调这个方法不会对BeanDefinition做任何修改，因为还没有任何后置处理器</span></span><br><span class="line">  <span class="comment">// 2. 如果使用AnnotactionConfigApplicationContext启动容器，则有一个后置处理器：org.springframework.context.annotation.internalConfigurationAnnotationProcessor</span></span><br><span class="line">  <span class="comment">//      用于加载使用@Component/@Service/@Controller等bean定义注解的类，并把类信息转成BeanDefinition保存到容器中</span></span><br><span class="line">  PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime</span></span><br><span class="line">  <span class="comment">// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)</span></span><br><span class="line">  <span class="keyword">if</span> (beanFactory.getTempClassLoader() == <span class="keyword">null</span> &amp;&amp; beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) &#123;</span><br><span class="line">    beanFactory.addBeanPostProcessor(<span class="keyword">new</span> LoadTimeWeaverAwareProcessor(beanFactory));</span><br><span class="line">    beanFactory.setTempClassLoader(<span class="keyword">new</span> ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>详细的Bean定义后置处理器的执行委托给<code>PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()</code>处理。这个方法才是具体处理实现。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 执行bean实例化前的后置处理器，用于对BeanDefinition增强，加载使用注解声明的类</span></span><br><span class="line"><span class="comment"> * 调用来源：AbstractApplication.refresh() -&gt; AbstractApplication.invokeBeanFactoryPostProcessors()</span></span><br><span class="line"><span class="comment"> * -&gt; 当前类：invokeBeanFactoryPostProcessors()</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> beanFactory</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> beanFactoryPostProcessors</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">invokeBeanFactoryPostProcessors</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">  ConfigurableListableBeanFactory beanFactory, List&lt;BeanFactoryPostProcessor&gt; beanFactoryPostProcessors)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Invoke BeanDefinitionRegistryPostProcessors first, if any.</span></span><br><span class="line">  <span class="comment">// 如果有BeanDefinitionRegistryPostProcessor则先执行</span></span><br><span class="line">  Set&lt;String&gt; processedBeans = <span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 1. 判断beanFactory是否是BeanDefinitionRegistry接口类型，</span></span><br><span class="line">  <span class="comment">// beanFactory为DefaultLitableBeanFactory实例，而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口，</span></span><br><span class="line">  <span class="keyword">if</span> (beanFactory <span class="keyword">instanceof</span> BeanDefinitionRegistry) &#123;</span><br><span class="line">    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;</span><br><span class="line">    <span class="comment">// 存放普通的后置处理器</span></span><br><span class="line">    List&lt;BeanFactoryPostProcessor&gt; regularPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="comment">// 存放BeanDefinitionRegistryPostProcessor，bean定义注册后置处理器</span></span><br><span class="line">    List&lt;BeanDefinitionRegistryPostProcessor&gt; registryProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="comment">//2. 处理入参beanFactoryPostProcessor列表，遍历所有工厂后置处理器</span></span><br><span class="line">    <span class="comment">// 把BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor区分，放在不同的List中</span></span><br><span class="line">    <span class="keyword">for</span> (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) &#123;</span><br><span class="line">      <span class="keyword">if</span> (postProcessor <span class="keyword">instanceof</span> BeanDefinitionRegistryPostProcessor) &#123;</span><br><span class="line">        BeanDefinitionRegistryPostProcessor registryProcessor =</span><br><span class="line">          (BeanDefinitionRegistryPostProcessor) postProcessor;</span><br><span class="line">        <span class="comment">// 执行postProcessBeanDefinitionRegistry方法</span></span><br><span class="line">        registryProcessor.postProcessBeanDefinitionRegistry(registry);</span><br><span class="line">        registryProcessors.add(registryProcessor);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        regularPostProcessors.add(postProcessor);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Do not initialize FactoryBeans here: We need to leave all regular beans</span></span><br><span class="line">    <span class="comment">// uninitialized to let the bean factory post-processors apply to them!</span></span><br><span class="line">    <span class="comment">// Separate between BeanDefinitionRegistryPostProcessors that implement</span></span><br><span class="line">    <span class="comment">// PriorityOrdered, Ordered, and the rest.</span></span><br><span class="line">    List&lt;BeanDefinitionRegistryPostProcessor&gt; currentRegistryProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.</span></span><br><span class="line">    <span class="comment">// 默认情况下postProcessorNames是空数组。</span></span><br><span class="line">    <span class="comment">// 如果项目中使用&lt;context:component-scan/&gt;或者&lt;context:annotation-config/&gt;或者@ComponentScan注解</span></span><br><span class="line">    <span class="comment">// postProcessorNames会有一个后置处理器：ConfigurationAnnotationProcessor</span></span><br><span class="line">    <span class="comment">// 这个类的postProcessBeanDefinitionRegistry()方法被调用时，</span></span><br><span class="line">    <span class="comment">// 会把用户使用`@Component`/`@Service`/`@Controller`/`@Import`/`@Bean`等注解定义的类转换成`BeanDefinition`对象并保存到容器中。</span></span><br><span class="line">    String[] postProcessorNames =</span><br><span class="line">      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, <span class="keyword">true</span>, <span class="keyword">false</span>);</span><br><span class="line">    <span class="keyword">for</span> (String ppName : postProcessorNames) &#123;</span><br><span class="line">      <span class="keyword">if</span> (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) &#123;</span><br><span class="line">        <span class="comment">// 执行BeanDefinitionRegistryPostProcessors后置处理器时bean实际上还没实例化，</span></span><br><span class="line">        <span class="comment">// 还是保存在内存中的BeanDefinition信息，所以显式调用getBean()方法，提前创建bean实例</span></span><br><span class="line">        <span class="comment">// 比如ConfigurationAnnotationProcessor这个类就是在getBean内部通过反射BeanUtils.instantiateClass(clazz)拿到实例</span></span><br><span class="line">        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));</span><br><span class="line">        processedBeans.add(ppName);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    sortPostProcessors(currentRegistryProcessors, beanFactory);</span><br><span class="line">    registryProcessors.addAll(currentRegistryProcessors);</span><br><span class="line">    <span class="comment">// ConfigurationAnnotationProcessor实现了PriorityOrdered接口，</span></span><br><span class="line">    <span class="comment">// 在这里就会类的postProcessBeanDefinitionRegistry()方法，加载所有使用注解声明的类定义信息并注册到容器中</span></span><br><span class="line">    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);</span><br><span class="line">    currentRegistryProcessors.clear();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.</span></span><br><span class="line">    <span class="comment">// 默认情况下数组是空的</span></span><br><span class="line">    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, <span class="keyword">true</span>, <span class="keyword">false</span>);</span><br><span class="line">    <span class="keyword">for</span> (String ppName : postProcessorNames) &#123;</span><br><span class="line">      <span class="comment">// 排除前面已经执行过的，实现了PriorityOrdered接口的PostProcessor</span></span><br><span class="line">      <span class="keyword">if</span> (!processedBeans.contains(ppName) &amp;&amp; beanFactory.isTypeMatch(ppName, Ordered.class)) &#123;</span><br><span class="line">        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));</span><br><span class="line">        processedBeans.add(ppName);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    sortPostProcessors(currentRegistryProcessors, beanFactory);</span><br><span class="line">    registryProcessors.addAll(currentRegistryProcessors);</span><br><span class="line">    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);</span><br><span class="line">    currentRegistryProcessors.clear();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.</span></span><br><span class="line">    <span class="comment">// 最后，执行剩下没有实现PriorityOrdered接口和Ordered接口的BeanDefinitionRegistryPostProcessor</span></span><br><span class="line">    <span class="keyword">boolean</span> reiterate = <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">while</span> (reiterate) &#123;</span><br><span class="line">      reiterate = <span class="keyword">false</span>;</span><br><span class="line">      <span class="comment">// 默认情况下数组是空的</span></span><br><span class="line">      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, <span class="keyword">true</span>, <span class="keyword">false</span>);</span><br><span class="line">      <span class="keyword">for</span> (String ppName : postProcessorNames) &#123;</span><br><span class="line">        <span class="comment">// 排除前面已经执行过的实现了PriorityOrdered接口或者实现了Ordered接口的PostProcessor</span></span><br><span class="line">        <span class="keyword">if</span> (!processedBeans.contains(ppName)) &#123;</span><br><span class="line">          currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));</span><br><span class="line">          processedBeans.add(ppName);</span><br><span class="line">          reiterate = <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      sortPostProcessors(currentRegistryProcessors, beanFactory);</span><br><span class="line">      registryProcessors.addAll(currentRegistryProcessors);</span><br><span class="line">      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);</span><br><span class="line">      currentRegistryProcessors.clear();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Now, invoke the postProcessBeanFactory callback of all processors handled so far.</span></span><br><span class="line">    <span class="comment">// 执行这些processor的postProcessBeanFactory()方法</span></span><br><span class="line">    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);</span><br><span class="line">    <span class="comment">// 执行普通的PostProcessor，这些PostProcessor是没有实现接口BeanDefinitionRegistryPostProcessor的</span></span><br><span class="line">    <span class="comment">// 直接执行这些实现类的postProcessBeanFactory()方法</span></span><br><span class="line">    <span class="comment">//regularPostProcessors = AnnotationConfigApplicationContext</span></span><br><span class="line">    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// Invoke factory processors registered with the context instance.</span></span><br><span class="line">    invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 到这里[bean定义注册后置处理器]都已经全部处理完，下面是接着处理[bean工厂后置处理器]</span></span><br><span class="line">  <span class="comment">// ===========================================================================</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// Do not initialize FactoryBeans here: We need to leave all regular beans</span></span><br><span class="line">  <span class="comment">// uninitialized to let the bean factory post-processors apply to them!</span></span><br><span class="line">  <span class="comment">// 不要再这里初始化FactoryBean，我们需要保留到所有未初始化的普通bean以便bean工厂后置处理可以处理</span></span><br><span class="line">  <span class="comment">// 如果开启了注解方式（项目中使用&lt;context:component-scan/&gt;或者&lt;context:annotation-config/&gt;或者@ComponentScan注解)，</span></span><br><span class="line">  <span class="comment">// 这里仍然可以获取到ConfigurationAnnotationProcessor，</span></span><br><span class="line">  <span class="comment">// 因为它也实现了BeanFactoryPostProcessor接口（postProcessBeanFactory()方法）</span></span><br><span class="line">  String[] postProcessorNames =</span><br><span class="line">    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, <span class="keyword">true</span>, <span class="keyword">false</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,</span></span><br><span class="line">  <span class="comment">// Ordered, and the rest.</span></span><br><span class="line">  List&lt;BeanFactoryPostProcessor&gt; priorityOrderedPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  List&lt;String&gt; orderedPostProcessorNames = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  List&lt;String&gt; nonOrderedPostProcessorNames = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  <span class="comment">// 根据bean后置处理器的接口类型分类</span></span><br><span class="line">  <span class="keyword">for</span> (String ppName : postProcessorNames) &#123;</span><br><span class="line">    <span class="comment">// 排除前面已经执行过的bean工厂后置处理器（BeanDefinitionRegistryPostProcessor)</span></span><br><span class="line">    <span class="keyword">if</span> (processedBeans.contains(ppName)) &#123;</span><br><span class="line">      <span class="comment">// skip - already processed in first phase above</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span> (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) &#123;</span><br><span class="line">      priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span> (beanFactory.isTypeMatch(ppName, Ordered.class)) &#123;</span><br><span class="line">      orderedPostProcessorNames.add(ppName);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      nonOrderedPostProcessorNames.add(ppName);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.</span></span><br><span class="line">  sortPostProcessors(priorityOrderedPostProcessors, beanFactory);</span><br><span class="line">  <span class="comment">// 执行ConfigurationAnnotationProcessor的postProcessBeanFactory()方法</span></span><br><span class="line">  <span class="comment">// 用于解析@Configuration注解的类中用@Bean注解的声明的bean，并把声明的bean转换BeanDefinition，注册到容器中</span></span><br><span class="line">  invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Next, invoke the BeanFactoryPostProcessors that implement Ordered.</span></span><br><span class="line">  List&lt;BeanFactoryPostProcessor&gt; orderedPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;(orderedPostProcessorNames.size());</span><br><span class="line">  <span class="keyword">for</span> (String postProcessorName : orderedPostProcessorNames) &#123;</span><br><span class="line">    orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));</span><br><span class="line">  &#125;</span><br><span class="line">  sortPostProcessors(orderedPostProcessors, beanFactory);</span><br><span class="line">  invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Finally, invoke all other BeanFactoryPostProcessors.</span></span><br><span class="line">  List&lt;BeanFactoryPostProcessor&gt; nonOrderedPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;(nonOrderedPostProcessorNames.size());</span><br><span class="line">  <span class="keyword">for</span> (String postProcessorName : nonOrderedPostProcessorNames) &#123;</span><br><span class="line">    nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));</span><br><span class="line">  &#125;</span><br><span class="line">  invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Clear cached merged bean definitions since the post-processors might have</span></span><br><span class="line">  <span class="comment">// modified the original metadata, e.g. replacing placeholders in values...</span></span><br><span class="line">  <span class="comment">// 清除元数据缓存，因为后置处理器可能已经修改的原始元数据，比如替换值的占位符。。。</span></span><br><span class="line">  beanFactory.clearMetadataCache();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行完<code>invokeBeanFactoryPostProcessors()</code>方法之后，对bean定义的修改已经完成。如果是使用注解方式定义bean，那么会通过<code>ConfigurationAnnotationProcessor</code>这个类把用户使用<code>@Component</code>/<code>@Service</code>/<code>@Controller</code>/<code>@Import</code>/<code>@Bean</code>/<code>@Configuration</code>等注解定义的类转换成<code>BeanDefinition</code>对象并保存到容器中。</p>
<p><strong>这一步会执行各种bean定义后置处理器。是IoC容器提供的一个非常重要的扩展点。同时，如果项目开启了注解方式，这一步就会把所有注解类加载成<code>BeanDefinition</code>并注册到容器中。</strong></p>
<p>接着详细解析一下<code>ConfigurationClassPostProcessor</code>是如何解析注解类并把bean定义注册到容器中。主要是通过这个类实现的<code>postProcessBeanDefinitionRegistry()</code>方法和<code>postProcessBeanFactory()</code>方法实现的。</p>
<p><code>ConfigurationClassPostProcessor</code>是专门用于解析注解bean定义后置处理器，非常非常重要。</p>
<p>先看下类图：</p>
<pre class="mermaid">graph BT

ConfigurationClassPostProcessor -.-> BeanClassLoaderAware
BeanClassLoaderAware -.-> Aware

ConfigurationClassPostProcessor -.-> ResourceLoaderAware
ResourceLoaderAware -.-> Aware

ConfigurationClassPostProcessor -.-> EnvironmentAware
EnvironmentAware -.-> Aware

ConfigurationClassPostProcessor -.-> PriorityOrdered
PriorityOrdered --> Ordered

ConfigurationClassPostProcessor -.-> BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor --> BeanFactoryPostProcessor</pre>



<p>通过类图可以看到<code>ConfigurationClassPostProcessor</code>同时具有<code>BeanDefinitiionRegistryPostProcessor</code>和<code>BeanFactoryPostProcessor</code>两个接口功能。</p>
<h4 id="postProcessBeanDefinitionRegistry-方法"><a href="#postProcessBeanDefinitionRegistry-方法" class="headerlink" title="postProcessBeanDefinitionRegistry()方法"></a>postProcessBeanDefinitionRegistry()方法</h4><p>方法主目录代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 实现BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法。在</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> org.springframework.context.support.AbstractApplicationContext 的refresh() -&gt; invokeBeanFactoryPostProcessors()方法会调用，</span></span><br><span class="line"><span class="comment">     * 作用是往容器中注册bean定义，包括使用`<span class="doctag">@Component</span>`/`<span class="doctag">@Service</span>`/`<span class="doctag">@Controller</span>`/`<span class="doctag">@Import</span>`/`<span class="doctag">@Bean</span>`等注解定义的类,</span></span><br><span class="line"><span class="comment">     * 这些类会被转换成BeanDefinition注册到容器中。</span></span><br><span class="line"><span class="comment">     * Derive further bean definitions from the configuration classes in the registry.</span></span><br><span class="line"><span class="comment">     * 从注册表中的配置类派生更多的bean定义。</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postProcessBeanDefinitionRegistry</span><span class="params">(BeanDefinitionRegistry registry)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">int</span> registryId = System.identityHashCode(registry);</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span>.registriesPostProcessed.contains(registryId)) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(</span><br><span class="line">      <span class="string">&quot;postProcessBeanDefinitionRegistry already called on this post-processor against &quot;</span> + registry);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span>.factoriesPostProcessed.contains(registryId)) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(</span><br><span class="line">      <span class="string">&quot;postProcessBeanFactory already called on this post-processor against &quot;</span> + registry);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">this</span>.registriesPostProcessed.add(registryId);</span><br><span class="line">  <span class="comment">// 非常重要的方法，在此方法内解析bean定义</span></span><br><span class="line">  processConfigBeanDefinitions(registry);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>前面的9行代码主要是用于防重的，暂不关注。主要是最后一行。</p>
<h5 id="processConfigBeanDefinitions-方法"><a href="#processConfigBeanDefinitions-方法" class="headerlink" title="processConfigBeanDefinitions()方法"></a>processConfigBeanDefinitions()方法</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Build and validate a configuration model based on the registry of</span></span><br><span class="line"><span class="comment">     * &#123;<span class="doctag">@link</span> Configuration&#125; classes.</span></span><br><span class="line"><span class="comment">     * 基于配置类的注册表构建并校验配置模型</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * 在这个processConfigBeanDefinitions方法中会做很多事情，</span></span><br><span class="line"><span class="comment">     * 会解析类上面标注了<span class="doctag">@ComponentScan</span>、<span class="doctag">@Import</span>、<span class="doctag">@bean</span>、<span class="doctag">@Component</span>等注解信息，</span></span><br><span class="line"><span class="comment">     * 对于<span class="doctag">@ComponentScan</span>会解析出需要扫描的包，然后利用ASM技术得到这个类，然后再次解析类上面的注解，</span></span><br><span class="line"><span class="comment">     * 对于<span class="doctag">@Import</span>来说，由于支持带入普通类、ImportSelector的实现类和ImportBeanDefinitionRegistrar的实现了，</span></span><br><span class="line"><span class="comment">     * 所以在解析<span class="doctag">@Import</span>的时候，会进行判断三种情况，</span></span><br><span class="line"><span class="comment">     * 然后执行ImportBeanDefinitionRegistrar和ImportSelector接口中的方法，对于导入的类，也会进行判断类中标注的注解（使用递归），</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">processConfigBeanDefinitions</span><span class="params">(BeanDefinitionRegistry registry)</span> </span>&#123;</span><br><span class="line">  List&lt;BeanDefinitionHolder&gt; configCandidates = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  <span class="comment">// 获取容器中所有的bean定义名称</span></span><br><span class="line">  String[] candidateNames = registry.getBeanDefinitionNames();</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (String beanName : candidateNames) &#123;</span><br><span class="line">    <span class="comment">// 通过bean名称拿到对应的bean定义</span></span><br><span class="line">    BeanDefinition beanDef = registry.getBeanDefinition(beanName);</span><br><span class="line">    <span class="comment">// 判断是否被解析过了</span></span><br><span class="line">    <span class="comment">// 如果BeanDefinition中configurationClass属性为full或者lite，则说明配置类已经处理过</span></span><br><span class="line">    <span class="keyword">if</span> (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">        logger.debug(<span class="string">&quot;Bean definition has already been processed as a configuration class: &quot;</span> + beanDef);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 判断是否为配置类，比如一个类上面使用@Configuraton注解</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span> (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, <span class="keyword">this</span>.metadataReaderFactory)) &#123;</span><br><span class="line">      <span class="comment">// 添加到候选的配置类集合中</span></span><br><span class="line">      configCandidates.add(<span class="keyword">new</span> BeanDefinitionHolder(beanDef, beanName));</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Return immediately if no @Configuration classes were found</span></span><br><span class="line">  <span class="comment">// 在bean列表中没有找到任何一个使用了@Configuration注解的类</span></span><br><span class="line">  <span class="keyword">if</span> (configCandidates.isEmpty()) &#123;</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Sort by previously determined @Order value, if applicable</span></span><br><span class="line">  <span class="comment">// 如果容器中扫描到多个使用了@Configuration注解的配置类，则根据@Order排序</span></span><br><span class="line">  <span class="comment">/* 比如如下的使用方式：可以返回第一个名为</span></span><br><span class="line"><span class="comment">        @Configuration</span></span><br><span class="line"><span class="comment">        public class JavaConfigA &#123;</span></span><br><span class="line"><span class="comment">            @Bean(name=&quot;bmw&quot;)</span></span><br><span class="line"><span class="comment">            public Car getBMW()&#123;</span></span><br><span class="line"><span class="comment">                // 返回实现了Car的名为bmw的单例</span></span><br><span class="line"><span class="comment">                return new BMW();</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">  configCandidates.sort((bd1, bd2) -&gt; &#123;</span><br><span class="line">    <span class="keyword">int</span> i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());</span><br><span class="line">    <span class="keyword">int</span> i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());</span><br><span class="line">    <span class="keyword">return</span> Integer.compare(i1, i2);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Detect any custom bean name generation strategy supplied through the enclosing application context</span></span><br><span class="line">  SingletonBeanRegistry sbr = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (registry <span class="keyword">instanceof</span> SingletonBeanRegistry) &#123;</span><br><span class="line">    sbr = (SingletonBeanRegistry) registry;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="keyword">this</span>.localBeanNameGeneratorSet) &#123;</span><br><span class="line">      <span class="comment">// CONFIGURATION_BEAN_NAME_GENERATOR=&quot;org.springframework.context.annotation.internalConfigurationBeanNameGenerator&quot;</span></span><br><span class="line">      BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(</span><br><span class="line">        AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);</span><br><span class="line">      <span class="keyword">if</span> (generator != <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="comment">// 设置@ComponentScan导入的bean的名字生成器</span></span><br><span class="line">        <span class="keyword">this</span>.componentScanBeanNameGenerator = generator;</span><br><span class="line">        <span class="comment">// 设置@Import导入进来的bean的名字生成器</span></span><br><span class="line">        <span class="keyword">this</span>.importBeanNameGenerator = generator;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span>.environment == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="comment">// 初始化一个标准的环境变量实例，里面会默认初始化喜欢环境变量，</span></span><br><span class="line">    <span class="comment">// 项目属性:System.getEnv()/System.getProperties()</span></span><br><span class="line">    <span class="keyword">this</span>.environment = <span class="keyword">new</span> StandardEnvironment();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Parse each @Configuration class</span></span><br><span class="line">  <span class="comment">// 创建一个@Configuration解析器</span></span><br><span class="line">  ConfigurationClassParser parser = <span class="keyword">new</span> ConfigurationClassParser(</span><br><span class="line">    <span class="keyword">this</span>.metadataReaderFactory, <span class="keyword">this</span>.problemReporter, <span class="keyword">this</span>.environment,</span><br><span class="line">    <span class="keyword">this</span>.resourceLoader, <span class="keyword">this</span>.componentScanBeanNameGenerator, registry);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 用于将之前加入的configCandidate进行去重，Spring内部是没有重复的，但是不能保证用户添加了重复，有可能一个项目定义了多个配置类</span></span><br><span class="line">  Set&lt;BeanDefinitionHolder&gt; candidates = <span class="keyword">new</span> LinkedHashSet&lt;&gt;(configCandidates);</span><br><span class="line">  <span class="comment">// 存放已经解析出来的配置类，用于判断是否已处理过</span></span><br><span class="line">  Set&lt;ConfigurationClass&gt; alreadyParsed = <span class="keyword">new</span> HashSet&lt;&gt;(configCandidates.size());</span><br><span class="line">  <span class="keyword">do</span> &#123;  <span class="comment">// 因为前面已经配置了数组非空，所以肯定有一个配置类才到这里</span></span><br><span class="line">    <span class="comment">// 解析配置类，这个方法里面的解析过程也是非常复杂而繁琐的。</span></span><br><span class="line">    <span class="comment">// 这个和AbstractApplicationContext.refresh() -&gt; obtainFreshBeanFactory()方法里面的解析xml配置有点类似</span></span><br><span class="line">    parser.parse(candidates);</span><br><span class="line">    parser.validate();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 拿到解析出来的配置类</span></span><br><span class="line">    Set&lt;ConfigurationClass&gt; configClasses = <span class="keyword">new</span> LinkedHashSet&lt;&gt;(parser.getConfigurationClasses());</span><br><span class="line">    <span class="comment">// 配置类已经解析完毕，从已经解析的列表</span></span><br><span class="line">    configClasses.removeAll(alreadyParsed);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Read the model and create bean definitions based on its content</span></span><br><span class="line">    <span class="comment">// 在上下文中读取并创建bean定义</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span>.reader == <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">this</span>.reader = <span class="keyword">new</span> ConfigurationClassBeanDefinitionReader(</span><br><span class="line">        registry, <span class="keyword">this</span>.sourceExtractor, <span class="keyword">this</span>.resourceLoader, <span class="keyword">this</span>.environment,</span><br><span class="line">        <span class="keyword">this</span>.importBeanNameGenerator, parser.getImportRegistry());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 把配置类中配置的bean定义加载注册到容器</span></span><br><span class="line">    <span class="keyword">this</span>.reader.loadBeanDefinitions(configClasses);</span><br><span class="line">    alreadyParsed.addAll(configClasses);</span><br><span class="line"></span><br><span class="line">    candidates.clear();</span><br><span class="line">    <span class="comment">// candidateNames包括了容器中的所有普通的bean定义（除了@Configuration注册的bean定义）</span></span><br><span class="line">    <span class="comment">// 再获取一下容器中的所有bean定义，如果有增加说明前面的已经有bean被解析并且注册到容器中</span></span><br><span class="line">    <span class="keyword">if</span> (registry.getBeanDefinitionCount() &gt; candidateNames.length) &#123;</span><br><span class="line">      String[] newCandidateNames = registry.getBeanDefinitionNames();</span><br><span class="line">      Set&lt;String&gt; oldCandidateNames = <span class="keyword">new</span> HashSet&lt;&gt;(Arrays.asList(candidateNames));</span><br><span class="line">      Set&lt;String&gt; alreadyParsedClasses = <span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line">      <span class="keyword">for</span> (ConfigurationClass configurationClass : alreadyParsed) &#123;</span><br><span class="line">        alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">for</span> (String candidateName : newCandidateNames) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!oldCandidateNames.contains(candidateName)) &#123;</span><br><span class="line">          BeanDefinition bd = registry.getBeanDefinition(candidateName);</span><br><span class="line">          <span class="keyword">if</span> (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, <span class="keyword">this</span>.metadataReaderFactory) &amp;&amp;</span><br><span class="line">              !alreadyParsedClasses.contains(bd.getBeanClassName())) &#123;</span><br><span class="line">            candidates.add(<span class="keyword">new</span> BeanDefinitionHolder(bd, candidateName));</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      candidateNames = newCandidateNames;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">while</span> (!candidates.isEmpty());</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes</span></span><br><span class="line">  <span class="keyword">if</span> (sbr != <span class="keyword">null</span> &amp;&amp; !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) &#123;</span><br><span class="line">    sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span>.metadataReaderFactory <span class="keyword">instanceof</span> CachingMetadataReaderFactory) &#123;</span><br><span class="line">    <span class="comment">// Clear cache in externally provided MetadataReaderFactory; this is a no-op</span></span><br><span class="line">    <span class="comment">// for a shared cache since it&#x27;ll be cleared by the ApplicationContext.</span></span><br><span class="line">    ((CachingMetadataReaderFactory) <span class="keyword">this</span>.metadataReaderFactory).clearCache();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>经过上述方法解析之后，已经把通过注解声明的类定义信息都加载到容器中。包括使用<code>@Component</code>，<code>@Service</code>，<code>@Controller</code>，<code>@ComponentScan</code>，<code>@ComponentScans</code>，<code>@Configuration</code>，@Bean，<code>@Import</code>，<code>@ImportSource</code>定义的类以及实现<code>ImportBeanDefinitionRegistrar</code>接口、<code>ImportSelector</code>接口，在接口中导入的类。解析成BeanDefinition然后加载到容器中保存到容器的<code>beanDefinitionMap</code>。</p>
<h6 id="parser-parse-candidates-解析候选配置类"><a href="#parser-parse-candidates-解析候选配置类" class="headerlink" title="parser.parse(candidates)解析候选配置类"></a>parser.parse(candidates)解析候选配置类</h6><p>解析配置类（使用@Configuration声明的类）。</p>
<p><code>parse()</code>方法只是做了简单的类型判断，最终的处理会交给<code>processConfigurationClass</code>方法，</p>
<p><code>processConfigurationClass</code>又调用了<code>doProcessConfigurationClass    </code>方法。</p>
<h6 id="doProcessConfigurationClass解析配置类具体方法"><a href="#doProcessConfigurationClass解析配置类具体方法" class="headerlink" title="doProcessConfigurationClass解析配置类具体方法"></a>doProcessConfigurationClass解析配置类具体方法</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Apply processing and build a complete &#123;<span class="doctag">@link</span> ConfigurationClass&#125; by reading the</span></span><br><span class="line"><span class="comment">     * annotations, members and methods from the source class. This method can be called</span></span><br><span class="line"><span class="comment">     * multiple times as relevant sources are discovered.</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * 1. 一个配置类的成员类(配置类内嵌套定义的类)也可能适配类，先遍历这些成员配置类，调用processConfigurationClass处理它们;</span></span><br><span class="line"><span class="comment">     * 2. 处理配置类上的注解<span class="doctag">@PropertySources</span>,<span class="doctag">@PropertySource</span></span></span><br><span class="line"><span class="comment">     * 3. 处理配置类上的注解<span class="doctag">@ComponentScans</span>,<span class="doctag">@ComponentScan</span></span></span><br><span class="line"><span class="comment">     * 4. 处理配置类上的注解<span class="doctag">@Import</span></span></span><br><span class="line"><span class="comment">     * 5. 处理配置类上的注解<span class="doctag">@ImportResource</span></span></span><br><span class="line"><span class="comment">     * 6. 处理配置类中每个带有<span class="doctag">@Bean</span>注解的方法</span></span><br><span class="line"><span class="comment">     * 7. 处理配置类所实现接口的缺省方法</span></span><br><span class="line"><span class="comment">     * 8. 检查父类是否需要处理，如果父类需要处理返回父类，否则返回null</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> configClass the configuration class being build</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> sourceClass a source class</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> the superclass, or &#123;<span class="doctag">@code</span> null&#125; if none found or previously processed</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">final</span> SourceClass <span class="title">doProcessConfigurationClass</span><span class="params">(ConfigurationClass configClass, SourceClass sourceClass)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 使用了@Configuration注解的类肯定是也是@Component注解的类，因为@Configuration继承了@Component</span></span><br><span class="line">  <span class="keyword">if</span> (configClass.getMetadata().isAnnotated(Component.class.getName())) &#123;</span><br><span class="line">    <span class="comment">// Recursively process any member (nested) classes first</span></span><br><span class="line">    <span class="comment">// 默认情况下会执行进去，但是方法内判断会不通过，相当于没做任何事情</span></span><br><span class="line">    processMemberClasses(configClass, sourceClass);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Process any @PropertySource annotations</span></span><br><span class="line">  <span class="comment">// 2、处理属性资源文件，使用@PropertySource注解可以导入Properties属性文件</span></span><br><span class="line">  <span class="keyword">for</span> (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(</span><br><span class="line">    sourceClass.getMetadata(), PropertySources.class,</span><br><span class="line">    org.springframework.context.annotation.PropertySource.class)) &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span>.environment <span class="keyword">instanceof</span> ConfigurableEnvironment) &#123;</span><br><span class="line">      processPropertySource(propertySource);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      logger.info(<span class="string">&quot;Ignoring @PropertySource annotation on [&quot;</span> + sourceClass.getMetadata().getClassName() +</span><br><span class="line">                  <span class="string">&quot;]. Reason: Environment must implement ConfigurableEnvironment&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Process any @ComponentScan annotations</span></span><br><span class="line">  <span class="comment">// 处理@ComponentScan/@ComponentScans注解，获取注解上的属性值，比如basePackages属性值</span></span><br><span class="line">  Set&lt;AnnotationAttributes&gt; componentScans = AnnotationConfigUtils.attributesForRepeatable(</span><br><span class="line">    sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);</span><br><span class="line">  <span class="keyword">if</span> (!componentScans.isEmpty() &amp;&amp;</span><br><span class="line">      !<span class="keyword">this</span>.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) &#123;</span><br><span class="line">    <span class="comment">// 解析basePackages指定的包和子包下的类并转换成BeanDefinition</span></span><br><span class="line">    <span class="keyword">for</span> (AnnotationAttributes componentScan : componentScans) &#123;</span><br><span class="line">      <span class="comment">// The config class is annotated with @ComponentScan -&gt; perform the scan immediately</span></span><br><span class="line">      Set&lt;BeanDefinitionHolder&gt; scannedBeanDefinitions =</span><br><span class="line">        <span class="keyword">this</span>.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());</span><br><span class="line">      <span class="comment">// Check the set of scanned definitions for any further config classes and parse recursively if needed</span></span><br><span class="line">      <span class="keyword">for</span> (BeanDefinitionHolder holder : scannedBeanDefinitions) &#123;</span><br><span class="line">        BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();</span><br><span class="line">        <span class="keyword">if</span> (bdCand == <span class="keyword">null</span>) &#123;</span><br><span class="line">          bdCand = holder.getBeanDefinition();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 如果扫描的basePackages指定的包和子包下的类还有使用了@Configuration注解则递归解析</span></span><br><span class="line">        <span class="keyword">if</span> (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, <span class="keyword">this</span>.metadataReaderFactory)) &#123;</span><br><span class="line">          parse(bdCand.getBeanClassName(), holder.getBeanName());</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Process any @Import annotations</span></span><br><span class="line">  <span class="comment">// 处理@Import注解，@Import(MyImportSelector.class)，MyImportSelector必须实现importSelector接口</span></span><br><span class="line">  <span class="comment">/* 用法如下：</span></span><br><span class="line"><span class="comment">        public class MyImportSelector implements ImportSelector &#123;</span></span><br><span class="line"><span class="comment">            @Override</span></span><br><span class="line"><span class="comment">            public String[] selectImports(AnnotationMetadata importingClassMetadata) &#123;</span></span><br><span class="line"><span class="comment">                return new String[] &#123;</span></span><br><span class="line"><span class="comment">                    MyImportSelectorBean.class.getName()</span></span><br><span class="line"><span class="comment">                &#125;;</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  <span class="comment">// @Import注解要和@Configuration一起用</span></span><br><span class="line">  processImports(configClass, sourceClass, getImports(sourceClass), <span class="keyword">true</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Process any @ImportResource annotations</span></span><br><span class="line">  <span class="comment">// 处理 @ImportResource(locations=&#123;&quot;classpath:applicationContext.xml&quot;&#125;)</span></span><br><span class="line">  <span class="comment">// @ImportResource注解要和@Configuration一起用</span></span><br><span class="line">  AnnotationAttributes importResource =</span><br><span class="line">    AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);</span><br><span class="line">  <span class="keyword">if</span> (importResource != <span class="keyword">null</span>) &#123;</span><br><span class="line">    String[] resources = importResource.getStringArray(<span class="string">&quot;locations&quot;</span>);</span><br><span class="line">    Class&lt;? extends BeanDefinitionReader&gt; readerClass = importResource.getClass(<span class="string">&quot;reader&quot;</span>);</span><br><span class="line">    <span class="keyword">for</span> (String resource : resources) &#123;</span><br><span class="line">      String resolvedResource = <span class="keyword">this</span>.environment.resolveRequiredPlaceholders(resource);</span><br><span class="line">      configClass.addImportedResource(resolvedResource, readerClass);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 处理@Configuration配置类中使用@Bean注解的方法，比如：</span></span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">        <span class="doctag">@Configuration</span></span></span><br><span class="line"><span class="comment">        public class AppConfig &#123;</span></span><br><span class="line"><span class="comment">            <span class="doctag">@Bean</span></span></span><br><span class="line"><span class="comment">            public myServiceImpl() &#123;</span></span><br><span class="line"><span class="comment">                return new MyServiceImpl();</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">  <span class="comment">// Process individual @Bean methods</span></span><br><span class="line">  Set&lt;MethodMetadata&gt; beanMethods = retrieveBeanMethodMetadata(sourceClass);</span><br><span class="line">  <span class="keyword">for</span> (MethodMetadata methodMetadata : beanMethods) &#123;</span><br><span class="line">    configClass.addBeanMethod(<span class="keyword">new</span> BeanMethod(methodMetadata, configClass));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Process default methods on interfaces</span></span><br><span class="line">  processInterfaces(configClass, sourceClass);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 处理配置类的父类，比如：</span></span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">        public class AnnotationConfigApplicationContextConfig</span></span><br><span class="line"><span class="comment">            extends AnnotationConfigApplicationContextConfigParent &#123;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        public class AnnotationConfigApplicationContextConfigParent &#123;</span></span><br><span class="line"><span class="comment">            <span class="doctag">@Bean</span></span></span><br><span class="line"><span class="comment">            public ParentConfigService parentConfigService() &#123;</span></span><br><span class="line"><span class="comment">                return new ParentConfigService();</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  <span class="comment">// Process superclass, if any</span></span><br><span class="line">  <span class="keyword">if</span> (sourceClass.getMetadata().hasSuperClass()) &#123;</span><br><span class="line">    String superclass = sourceClass.getMetadata().getSuperClassName();</span><br><span class="line">    <span class="comment">// 排除java.xxx开头的包类，因为所有的类终究会继承顶层父类java.lang.Object。</span></span><br><span class="line">    <span class="keyword">if</span> (superclass != <span class="keyword">null</span> &amp;&amp; !superclass.startsWith(<span class="string">&quot;java&quot;</span>) &amp;&amp;</span><br><span class="line">        !<span class="keyword">this</span>.knownSuperclasses.containsKey(superclass)) &#123;</span><br><span class="line">      <span class="keyword">this</span>.knownSuperclasses.put(superclass, configClass);</span><br><span class="line">      <span class="comment">// Superclass found, return its annotation metadata and recurse</span></span><br><span class="line">      <span class="keyword">return</span> sourceClass.getSuperClass();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// No superclass -&gt; processing is complete</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>所有注解类的bean定义都已经解析完毕，回到<code>processConfigBeanDefinition</code>方法，然后在另外方法注册bean定义。</p>
<h6 id="this-reader-loadBeanDefinitions-configClasses-注册bean定义"><a href="#this-reader-loadBeanDefinitions-configClasses-注册bean定义" class="headerlink" title="this.reader.loadBeanDefinitions(configClasses)注册bean定义"></a>this.reader.loadBeanDefinitions(configClasses)注册bean定义</h6><p>经过<code>parser.parse()</code>方法之后，所有注解类都已经转化成bean定义。然后在<code>loadBeanDefinitions</code>方法中注册bean定义到容器中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">loadBeanDefinitionsForConfigurationClass</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">  ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 省略其他无关主题的判断……</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (configClass.isImported()) &#123;</span><br><span class="line">    registerBeanDefinitionForImportedConfigurationClass(configClass);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">for</span> (BeanMethod beanMethod : configClass.getBeanMethods()) &#123;</span><br><span class="line">    <span class="comment">// 注册@Bean注解方法指定的bean定义到容器中</span></span><br><span class="line">    loadBeanDefinitionsForBeanMethod(beanMethod);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 配置类是否使用了@ImportResource注解，通过这个注入可以导入其他的类</span></span><br><span class="line">  loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());</span><br><span class="line">  <span class="comment">// 配置类是否实现ImportBeanDefinitionRegistrar接口。如果有则执行接口registerBeanDefinitions方法</span></span><br><span class="line">  loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>到此<code>processConfigBeanDefinitions()</code>方法处理完毕，所有注解类都已经转化成bean定义并注册到容器中。</p>
<p>再回到ConfigurationClassPostProcessor.postProcessorBeanDefinitionRegistry()`方法。</p>
<p>再回到<code>PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessor()</code>方法，</p>
<p>再回到<code>PostProcessorRegistrationDeletegate.invokeBeanFactoryPostProcessors()</code>方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);</span><br></pre></td></tr></table></figure>

<h4 id="invokeBeanDefinitionRegistryPostProcessors-currentRegistryProcessors-registry-方法执行流程图"><a href="#invokeBeanDefinitionRegistryPostProcessors-currentRegistryProcessors-registry-方法执行流程图" class="headerlink" title="invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法执行流程图"></a>invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法执行流程图</h4><pre class="mermaid">sequenceDiagram
autonumber

AbstractApplicationContext ->> PostProcessorRegistrationDelegate: invokeBeanFactoryPostProcessors()
PostProcessorRegistrationDelegate ->> ConfigurationClassPostProcessor: postProcessorBeanDefinitionRegistry()
ConfigurationClassPostProcessor ->> ConfigurationClassPostProcessor:processorConfigBeanDefinitions()

ConfigurationClassPostProcessor ->> ConfigurationClassParser:parse(condidates)
ConfigurationClassParser ->> ConfigurationClassParser:processConfigurationClass()
ConfigurationClassParser ->> ConfigurationClassParser:doProcessConfigurationClass(configClass, sourceClass)

ConfigurationClassParser ->> ConfigurationClassParser.doProcessConfigurationClass():processPropertySource
ConfigurationClassParser ->> ConfigurationClassParser.doProcessConfigurationClass():componentScan()
ConfigurationClassParser ->> ConfigurationClassParser.doProcessConfigurationClass():processImports()
ConfigurationClassParser ->> ConfigurationClassParser.doProcessConfigurationClass():importResource
ConfigurationClassParser ->> ConfigurationClassParser.doProcessConfigurationClass():beanMethod()
ConfigurationClassParser ->> ConfigurationClassParser.doProcessConfigurationClass():superClass()

ConfigurationClassPostProcessor ->> ConfigurationClassBeanDefinitionReader:loadBeanDefinitions()
ConfigurationClassBeanDefinitionReader ->> ConfigurationClassBeanDefinitionReader:loadBeanDefinitionsForConfigurationClass()
ConfigurationClassBeanDefinitionReader ->> ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass:registerBeanDefinitionForImportedConfigurationClass()
ConfigurationClassBeanDefinitionReader ->> ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass:loanBeanDefinitionsForBeanMethod()
ConfigurationClassBeanDefinitionReader ->> ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass:loadBeanDefinitionsFromImportedResources()
ConfigurationClassBeanDefinitionReader ->> ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass:loadBeanDefinitionsFromRegstrars()</pre>

<h4 id="bean定义后置处理器使用"><a href="#bean定义后置处理器使用" class="headerlink" title="bean定义后置处理器使用"></a>bean定义后置处理器使用</h4><p>经过<code>invokeBeanDefinitionFactoryPostProcessor()</code>方法的理解，我们知道了这个方法提供了用户注册<code>BeanDefinition</code>扩展。这个是Spring框架第一个非常非常重要的扩展点，通过实现如下两个接口实现就可以使用扩展。</p>
<ol>
<li>实现<code>BeanFactoryPostProcessor</code>接口</li>
<li>实现<code>BeanDefinitionRegistryPostProcessor</code>接口</li>
</ol>
<p>下面我们通过自定义的bean定义后置处理器实现类进一步学习如何修改容器的中的<code>BeanDefinition</code>，如何注册自己的<code>BeanDefinition</code>到容器中。</p>
<p>由于篇幅太大，在另外一篇<a href="/Users/ubuntuvim/code/xcoding/source/_posts/Spring/Spring%E5%90%8E%E7%BD%AE%E5%A4%84%E7%90%86%E5%99%A8.md">《Spring后置处理器》</a>中详解。</p>
<h3 id="registerBeanPostProcessors-beanFactory"><a href="#registerBeanPostProcessors-beanFactory" class="headerlink" title="registerBeanPostProcessors(beanFactory)"></a>registerBeanPostProcessors(beanFactory)</h3><blockquote>
<p>注册bean工厂的后置处理器（仅仅是把Spring内部定义的和用户定义的<code>BeanPostProcessor</code>注册到容器中，后面的步骤才会真正执行），这些后置处理器在bean的构造方法执行之后，在执行init方法前后执行指定的逻辑。</p>
<p>主要是通过的接口的两个方法实现，一个是在所有的bean的<code>InitializingBean</code>的<code>afterPropertiesSet()</code>方法或者是自定义的init方法（比如<code>@PostConstruct</code>注解的方法）之前执行的回调方法<code>postProcessBeforeInitialization()</code>；一个是在所有的bean的<code>InitializingBean</code>的<code>afterPropertiesSet()</code>方法或者是自定义的init方法（比如<code>@PostConstruct</code>注解的方法）之后执行的回调方法<code>postProcessAfterInitialization()</code></p>
<p>后置处理器的执行顺序可以看第二章《Spring中Bean生命周期》</p>
</blockquote>
<p>是不是就是上述所说的呢？？带着疑问我们接着看源码。</p>
<p>回到<code>AbstractApplicationContext.refresh()</code>方法，从方法内调用的<code>registerBeanPostProcessors()</code>继续。</p>
<p>这个方法只是注册后置处理，并且委托给<code>PostProcessorRegistrationDeletgate</code>类处理具体注册逻辑。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">registerBeanPostProcessors</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> </span>&#123;</span><br><span class="line">  PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, <span class="keyword">this</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>来来来，仔细看一眼这个方法处理细节，是不是有一种似曾相似的感觉。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">registerBeanPostProcessors</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">  ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//        postProcessorNames = &#123;String[2]@1992&#125;</span></span><br><span class="line">  <span class="comment">//        0 = &quot;org.springframework.context.annotation.internalAutowiredAnnotationProcessor&quot;</span></span><br><span class="line">  <span class="comment">//        1 = &quot;org.springframework.context.annotation.internalCommonAnnotationProcessor&quot;</span></span><br><span class="line">  String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, <span class="keyword">true</span>, <span class="keyword">false</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Register BeanPostProcessorChecker that logs an info message when</span></span><br><span class="line">  <span class="comment">// a bean is created during BeanPostProcessor instantiation, i.e. when</span></span><br><span class="line">  <span class="comment">// a bean is not eligible for getting processed by all BeanPostProcessors.</span></span><br><span class="line">  <span class="keyword">int</span> beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + <span class="number">1</span> + postProcessorNames.length;</span><br><span class="line">  beanFactory.addBeanPostProcessor(<span class="keyword">new</span> BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 根据BeanPostProcessor的实现不同区分开</span></span><br><span class="line">  <span class="comment">// Separate between BeanPostProcessors that implement PriorityOrdered,</span></span><br><span class="line">  <span class="comment">// Ordered, and the rest.</span></span><br><span class="line">  List&lt;BeanPostProcessor&gt; priorityOrderedPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  List&lt;BeanPostProcessor&gt; internalPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  List&lt;String&gt; orderedPostProcessorNames = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  List&lt;String&gt; nonOrderedPostProcessorNames = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">  <span class="keyword">for</span> (String ppName : postProcessorNames) &#123;</span><br><span class="line">    <span class="keyword">if</span> (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) &#123;</span><br><span class="line">      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);</span><br><span class="line">      priorityOrderedPostProcessors.add(pp);</span><br><span class="line">      <span class="comment">// 同时实现了PriorityOrdered接口和MergedBeanPostProcessor接口的实现类</span></span><br><span class="line">      <span class="keyword">if</span> (pp <span class="keyword">instanceof</span> MergedBeanDefinitionPostProcessor) &#123;</span><br><span class="line">        internalPostProcessors.add(pp);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span> (beanFactory.isTypeMatch(ppName, Ordered.class)) &#123;</span><br><span class="line">      orderedPostProcessorNames.add(ppName);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      nonOrderedPostProcessorNames.add(ppName);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// First, register the BeanPostProcessors that implement PriorityOrdered.</span></span><br><span class="line">  sortPostProcessors(priorityOrderedPostProcessors, beanFactory);</span><br><span class="line">  registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Next, register the BeanPostProcessors that implement Ordered.</span></span><br><span class="line">  List&lt;BeanPostProcessor&gt; orderedPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;(orderedPostProcessorNames.size());</span><br><span class="line">  <span class="keyword">for</span> (String ppName : orderedPostProcessorNames) &#123;</span><br><span class="line">    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);</span><br><span class="line">    orderedPostProcessors.add(pp);</span><br><span class="line">    <span class="comment">// 同时实现了Ordered接口和MergeBeanPostProcessor接口的</span></span><br><span class="line">    <span class="keyword">if</span> (pp <span class="keyword">instanceof</span> MergedBeanDefinitionPostProcessor) &#123;</span><br><span class="line">      internalPostProcessors.add(pp);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  sortPostProcessors(orderedPostProcessors, beanFactory);</span><br><span class="line">  <span class="comment">// 每次注册到容器时都是先删除再添加，所以不会重复</span></span><br><span class="line">  registerBeanPostProcessors(beanFactory, orderedPostProcessors);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Now, register all regular BeanPostProcessors.</span></span><br><span class="line">  List&lt;BeanPostProcessor&gt; nonOrderedPostProcessors = <span class="keyword">new</span> ArrayList&lt;&gt;(nonOrderedPostProcessorNames.size());</span><br><span class="line">  <span class="keyword">for</span> (String ppName : nonOrderedPostProcessorNames) &#123;</span><br><span class="line">    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);</span><br><span class="line">    nonOrderedPostProcessors.add(pp);</span><br><span class="line">    <span class="comment">// 没有实现PriorityOrdered接口，没有实现Ordered接口，但是仅实现了MergedBeanPosProcessor接口的</span></span><br><span class="line">    <span class="keyword">if</span> (pp <span class="keyword">instanceof</span> MergedBeanDefinitionPostProcessor) &#123;</span><br><span class="line">      internalPostProcessors.add(pp);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 每次注册到容器时都是先删除再添加，所以不会重复</span></span><br><span class="line">  registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Finally, re-register all internal BeanPostProcessors.</span></span><br><span class="line">  <span class="comment">// 重新注册内部BeanPostProcessor，作用是把内部BeabPostProcessor放在数组最后面</span></span><br><span class="line">  sortPostProcessors(internalPostProcessors, beanFactory);</span><br><span class="line">  <span class="comment">// 每次注册到容器时都是先删除再添加，所以不会重复</span></span><br><span class="line">  registerBeanPostProcessors(beanFactory, internalPostProcessors);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Re-register post-processor for detecting inner beans as ApplicationListeners,</span></span><br><span class="line">  <span class="comment">// moving it to the end of the processor chain (for picking up proxies etc).</span></span><br><span class="line">  <span class="comment">// 重新注册，目的就是把此BeanPostProcessor放在数组末尾</span></span><br><span class="line">  beanFactory.addBeanPostProcessor(<span class="keyword">new</span> ApplicationListenerDetector(applicationContext));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这方方法的处理逻辑和前面的bean定义后置处理逻辑几乎是一样的，都是先做分类、排序。唯一不同的是本方法不会执行后置处理器，而只是注册到容器中。这些后置处理器的执行放在<code>AbstractApplicationContext.refresh()</code>的<code>finishBeanFactoryInitialization(beanFactory);</code>里面执行。这些注册好的后置处理器会在bean实例化、属性初始化的过程中执行。详细执行过程到<code>finishBeanFactoryInitialization()</code>方法再介绍。</p>
<h3 id="initMessageSource"><a href="#initMessageSource" class="headerlink" title="initMessageSource()"></a>initMessageSource()</h3><p>bean后置处理器注册完毕之后，接着是初始化信息资源。</p>
<p>这个方法用于初始化上下文的消息资源，比如message-xxx.properties。</p>
<p>用户可以自定义一个名为messageSource的bean用于指定某些properties属性的国际化信息。</p>
<p>这个方法的源码也比较简单，也不是Spring框架学习的重点，就简单做一个例子学习如何使用即可。</p>
<h4 id="Spring方法源码"><a href="#Spring方法源码" class="headerlink" title="Spring方法源码"></a>Spring方法源码</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">initMessageSource</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 获取容器实例，也可以直接通过入参传递</span></span><br><span class="line">  ConfigurableListableBeanFactory beanFactory = getBeanFactory();</span><br><span class="line">  <span class="comment">// 监测容器中是否已经注册了名为messageSource的bean</span></span><br><span class="line">  <span class="keyword">if</span> (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) &#123;</span><br><span class="line">    <span class="comment">// 获取bean实例，这里显式调用getBean()方法提前实例化bean</span></span><br><span class="line">    <span class="keyword">this</span>.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);</span><br><span class="line">    <span class="comment">// Make MessageSource aware of parent MessageSource.</span></span><br><span class="line">    <span class="comment">// 果对应的messageSource是一个HierarchicalMessageSource，</span></span><br><span class="line">    <span class="comment">// 则会在父容器存在的情况下取父容器对应的messageSource作为当前messageSource的parentMessageSource</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span>.parent != <span class="keyword">null</span> &amp;&amp; <span class="keyword">this</span>.messageSource <span class="keyword">instanceof</span> HierarchicalMessageSource) &#123;</span><br><span class="line">      HierarchicalMessageSource hms = (HierarchicalMessageSource) <span class="keyword">this</span>.messageSource;</span><br><span class="line">      <span class="keyword">if</span> (hms.getParentMessageSource() == <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="comment">// Only set parent context as parent MessageSource if no parent MessageSource</span></span><br><span class="line">        <span class="comment">// registered already.</span></span><br><span class="line">        hms.setParentMessageSource(getInternalParentMessageSource());</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;Using MessageSource [&quot;</span> + <span class="keyword">this</span>.messageSource + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 如果容器中还没有名为messageSource的bean则创建并注册一个，实例是DelegatingMessageSource对象</span></span><br><span class="line">    <span class="comment">// Use empty MessageSource to be able to accept getMessage calls.</span></span><br><span class="line">    DelegatingMessageSource dms = <span class="keyword">new</span> DelegatingMessageSource();</span><br><span class="line">    dms.setParentMessageSource(getInternalParentMessageSource());</span><br><span class="line">    <span class="keyword">this</span>.messageSource = dms;</span><br><span class="line">    beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, <span class="keyword">this</span>.messageSource);</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;No &#x27;&quot;</span> + MESSAGE_SOURCE_BEAN_NAME + <span class="string">&quot;&#x27; bean, using [&quot;</span> + <span class="keyword">this</span>.messageSource + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="使用例子"><a href="#使用例子" class="headerlink" title="使用例子"></a>使用例子</h4><p>首先定义三个Properties文件，一个是默认使用的配置，一个是中文环境下使用的配置，一个是英文环境下使用的配置。Spring会自动根据所在系统环境读取对应的配置。</p>
<ul>
<li>msgSource.properties</li>
<li>msgSource_zh.properties</li>
<li>msgSource_en.properties</li>
</ul>
<p>需要注意的是这三个文件中的key是一样的，只是内容会不一样。</p>
<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># msgSource.properties</span></span><br><span class="line"><span class="meta">test.key</span>=<span class="string">这个时候默认值。</span></span><br></pre></td></tr></table></figure>

<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># msgSource_zh.properties</span></span><br><span class="line"><span class="meta">test.key</span>=<span class="string">中文环境下的值。</span></span><br></pre></td></tr></table></figure>

<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># msgSource_en.properties</span></span><br><span class="line"><span class="meta">test.key</span>=<span class="string">english value</span></span><br></pre></td></tr></table></figure>

<p>然后手动定义一个名为messageSource的bean。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.ubuntuvim.spring.msg;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.MessageSource;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.ComponentScan;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.support.ResourceBundleMessageSource;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: ubuntuvim</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2020/9/26 上午12:37</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AppConfig</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 定义messageSource，并交给容器管理，容器在启动的时候就会执行到</span></span><br><span class="line"><span class="comment">     * AbstractApplicationContext.refresh() -&gt; initMessageSource()方法</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> MessageSource <span class="title">messageSource</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">        这个接口有三个实现类：</span></span><br><span class="line"><span class="comment">        1. ResourceBundleMessageSource：</span></span><br><span class="line"><span class="comment">        2. ReloadableResourceBundleMessageSource：</span></span><br><span class="line"><span class="comment">        3. StaticMessageSource：</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        ResourceBundleMessageSource messageSource = <span class="keyword">new</span> ResourceBundleMessageSource();</span><br><span class="line">        messageSource.setDefaultEncoding(<span class="string">&quot;UTF-8&quot;</span>);</span><br><span class="line">        <span class="comment">// 一定要设置配置文件的名称前缀，我定义的properties文件的都是以msgSource开头的</span></span><br><span class="line">        messageSource.setBasename(<span class="string">&quot;msgSource&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> messageSource;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过<code>messageSource</code>这个bean获取配置值。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.ubuntuvim.spring.msg;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Locale;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationContext;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.MessageSource;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.AnnotationConfigApplicationContext;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.support.AbstractApplicationContext;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: ubuntuvim</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2020/9/26 上午12:46</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MsgSourceTest</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        ApplicationContext applicationContext = <span class="keyword">new</span> AnnotationConfigApplicationContext(AppConfig.class);</span><br><span class="line">        MessageSource messageSource = (MessageSource) applicationContext.getBean(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME);</span><br><span class="line">        <span class="comment">// 指定获取中文环境下的值</span></span><br><span class="line">        String message = messageSource.getMessage(<span class="string">&quot;test.key&quot;</span>, <span class="keyword">null</span>, Locale.CHINESE);</span><br><span class="line">        System.out.println(message);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 指定获取英文环境下的值</span></span><br><span class="line">        String message2 = messageSource.getMessage(<span class="string">&quot;test.key&quot;</span>, <span class="keyword">null</span>, Locale.ENGLISH);</span><br><span class="line">        System.out.println(message2);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 指定获取默认值getDefault会自动根据系统环境判断使用那个环境的配置文件</span></span><br><span class="line">        String message3 = messageSource.getMessage(<span class="string">&quot;test.key&quot;</span>, <span class="keyword">null</span>, Locale.getDefault());</span><br><span class="line">        System.out.println(message3);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 如果找不到匹配的语言环境配置文件则使用msgSource.properties的配置</span></span><br><span class="line">        String message4 = messageSource.getMessage(<span class="string">&quot;test.key&quot;</span>, <span class="keyword">null</span>, <span class="keyword">null</span>);</span><br><span class="line">        System.out.println(message4);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>运行结果：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">中文环境下的值。</span><br><span class="line">english value</span><br><span class="line">中文环境下的值。</span><br><span class="line">中文环境下的值。</span><br></pre></td></tr></table></figure>



<p>在紧接着是<code>AbstractApplicationContext.refresh()</code>的<code>initApplicationEventMulticaster()</code>方法。</p>
<h3 id="initApplicationEventMulticaster"><a href="#initApplicationEventMulticaster" class="headerlink" title="initApplicationEventMulticaster()"></a>initApplicationEventMulticaster()</h3><p>这个方法和前面的<code>initMessageSource</code>很类似，指示作用不同。本方法用于初始化事件派发器。主要是通过观察者模式实现（叫作发布订阅模式Publish/Subscribe，定义对象间一对多的依赖关系，使得每当一个对象改变状态，则所有依赖与它的对象都会得到通知，并被自动更新。）。事件的发布、监听不是学习Spring框架的主要内容，就做一个简单的案例学习略过。</p>
<p>同时需要注意的是这个方法和接下来的<code>registerListeners()</code>方法是有关联关系的。<code>initApplicationEvenMultiCaseter()</code>方法初始化的事件会在<code>registrListeners()</code>方法中被监听。</p>
<h4 id="Spring中的观察者模式"><a href="#Spring中的观察者模式" class="headerlink" title="Spring中的观察者模式"></a>Spring中的观察者模式</h4><p>Spring在事件处理机制中使用了观察者模式：</p>
<ul>
<li>事件，<code>ApplicationEvent</code>，该抽象类继承了<code>EventObject</code>，<code>EventObject</code>是JDK中的类，并建议所有的事件都应该继承自<code>EventObject</code>。</li>
<li>事件监听器，<code>ApplicationListener</code>，是一个接口，该接口继承了<code>EventListener</code>接口。<code>EventListener</code>接口是JDK中的，建议所有的事件监听器都应该继承<code>EventListener</code>。</li>
<li>事件发布，<code>ApplicationEventPublisher</code>，<code>ApplicationContext</code>继承了该接口，在<code>ApplicationContext</code>的抽象实现类<code>AbstractApplicationContext</code>中做了实现</li>
</ul>
<p><strong>工作起来就是，事件发布器发布事件，监听器接受事件，结束。</strong></p>
<h4 id="源码"><a href="#源码" class="headerlink" title="源码"></a>源码</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">initApplicationEventMulticaster</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  ConfigurableListableBeanFactory beanFactory = getBeanFactory();</span><br><span class="line">  <span class="comment">// 判断容器中是否存在bdName为applicationEventMulticaster的bean</span></span><br><span class="line">  <span class="keyword">if</span> (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) &#123;</span><br><span class="line">    <span class="keyword">this</span>.applicationEventMulticaster =</span><br><span class="line">      beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;Using ApplicationEventMulticaster [&quot;</span> + <span class="keyword">this</span>.applicationEventMulticaster + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 如果容器中还没有创建过名为applicationEvMulticaster的bean则创建一个SimpleApplicationEventMulticaster</span></span><br><span class="line">    <span class="comment">//</span></span><br><span class="line">    <span class="keyword">this</span>.applicationEventMulticaster = <span class="keyword">new</span> SimpleApplicationEventMulticaster(beanFactory);</span><br><span class="line">    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, <span class="keyword">this</span>.applicationEventMulticaster);</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;No &#x27;&quot;</span> + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + <span class="string">&quot;&#x27; bean, using &quot;</span> +</span><br><span class="line">                   <span class="string">&quot;[&quot;</span> + <span class="keyword">this</span>.applicationEventMulticaster.getClass().getSimpleName() + <span class="string">&quot;]&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="使用案例"><a href="#使用案例" class="headerlink" title="使用案例"></a>使用案例</h4><p>定义一个事件。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.ubuntuvim.spring.event;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationEvent;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 定义一个事件</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: ubuntuvim</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2020/9/26 上午1:55</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyEvent</span> <span class="keyword">extends</span> <span class="title">ApplicationEvent</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = <span class="number">21162432L</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 事件的内容必须是实现Serializable接口的</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> source</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">MyEvent</span><span class="params">(EventContent source)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(source);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>定义一个监听器</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.ubuntuvim.spring.event;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationEvent;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationListener;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.event.EventListener;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 定义一个事件监听器。</span></span><br><span class="line"><span class="comment"> * Spring4.1之后有两种实现监听器：</span></span><br><span class="line"><span class="comment"> * 1. 实现ApplicationListener接口</span></span><br><span class="line"><span class="comment"> * 2. 使用<span class="doctag">@EventListener</span>注解</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: ubuntuvim</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2020/9/26 上午2:02</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyListener</span> <span class="keyword">implements</span> <span class="title">ApplicationListener</span>&lt;<span class="title">MyEvent</span>&gt; </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onApplicationEvent</span><span class="params">(MyEvent event)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="keyword">this</span>.getClass().getName() + <span class="string">&quot;监听到了发布的事件，事件内容是: &quot;</span> + event.getSource());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@EventListener</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">listenerEvent</span><span class="params">(MyEvent myEvent)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;使用@EventListener方式，监听到了发布的事件，事件内容是: &quot;</span> + myEvent.getSource());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>通过容器发布事件。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.ubuntuvim.spring.event;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationContext;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.AnnotationConfigApplicationContext;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span>: ubuntuvim</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span>: 2020/9/26 上午2:05</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EventTest</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        ApplicationContext applicationContext = <span class="keyword">new</span> AnnotationConfigApplicationContext(AppConfig.class);</span><br><span class="line">        <span class="comment">// 发布事件</span></span><br><span class="line">        applicationContext.publishEvent(<span class="keyword">new</span> MyEvent(<span class="keyword">new</span> EventContent(<span class="string">&quot;中国的原子弹搞出来了。&quot;</span>)));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>运行结果：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">使用@EventListener方式，监听到了发布的事件，事件内容是: EventContent&#123;content=&#x27;中国的原子弹搞出来了。&#x27;&#125;</span><br><span class="line">com.ubuntuvim.spring.event.MyListener监听到了发布的事件，事件内容是: EventContent&#123;content=&#x27;中国的原子弹搞出来了。&#x27;&#125;</span><br></pre></td></tr></table></figure>



<h3 id="onRefresh"><a href="#onRefresh" class="headerlink" title="onRefresh()"></a>onRefresh()</h3><p>这个方法留给子类扩展用。用于初始化一些子类特有的功能。</p>
<p>比如<code>AbstractRefreshableWebApplicationContext</code>、<code>StaticWebApplicationContext</code>和<code>GenericWebApplicationContext</code>这三个子类都重写了这个方法，用于初始化了一些SpringMVC相关的主题资源。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onRefresh</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.themeSource = UiApplicationContextUtils.initThemeSource(<span class="keyword">this</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="registerListeners"><a href="#registerListeners" class="headerlink" title="registerListeners()"></a>registerListeners()</h3><p>这个方法用于注册事件监听器，和前面<code>initApplicationEventMulticaster()</code>方法是配合使用的。前面例子中的<code>MyListener</code>就是在这里注册的，但是也仅仅是注册监听器，还没有发布任何事件，事件的发布在最后面容器所有bean都实例化、属性初始化完毕之后的方法<code>finishRefresh()</code>中发布，就是这行代码<code>publishEvent(new ContextRefreshedEvent(this));</code>。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">registerListeners</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// Register statically specified listeners first.</span></span><br><span class="line">  <span class="keyword">for</span> (ApplicationListener&lt;?&gt; listener : getApplicationListeners()) &#123;</span><br><span class="line">    getApplicationEventMulticaster().addApplicationListener(listener);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Do not initialize FactoryBeans here: We need to leave all regular beans</span></span><br><span class="line">  <span class="comment">// uninitialized to let post-processors apply to them!</span></span><br><span class="line">  <span class="comment">// 注册用户定义的监听器，比如com.ubuntuvim.spring.event.MyListener就是在这里注册的。</span></span><br><span class="line">  String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, <span class="keyword">true</span>, <span class="keyword">false</span>);</span><br><span class="line">  <span class="keyword">for</span> (String listenerBeanName : listenerBeanNames) &#123;</span><br><span class="line">    <span class="comment">// getApplicationEventMulticaster()拿到的就是refresh()方法中initApplicationEventMulticaster()定义的发布器</span></span><br><span class="line">    getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Publish early application events now that we finally have a multicaster...</span></span><br><span class="line">  Set&lt;ApplicationEvent&gt; earlyEventsToProcess = <span class="keyword">this</span>.earlyApplicationEvents;</span><br><span class="line">  <span class="keyword">this</span>.earlyApplicationEvents = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (earlyEventsToProcess != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">for</span> (ApplicationEvent earlyEvent : earlyEventsToProcess) &#123;</span><br><span class="line">      getApplicationEventMulticaster().multicastEvent(earlyEvent);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="finishBeanFactoryInitialization-beanFactory"><a href="#finishBeanFactoryInitialization-beanFactory" class="headerlink" title="finishBeanFactoryInitialization(beanFactory)"></a>finishBeanFactoryInitialization(beanFactory)</h3><p>这个方法是最重要也是最最最复杂的，包括各种<code>BeanPostProcess</code>实现类的调用，以及复杂的bean实例化，bean属性的初始化操作。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">finishBeanFactoryInitialization</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// Initialize conversion service for this context.</span></span><br><span class="line">  <span class="comment">// 初始化上下文的转换服务</span></span><br><span class="line">  <span class="keyword">if</span> (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &amp;&amp;</span><br><span class="line">      beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) &#123;</span><br><span class="line">    beanFactory.setConversionService(</span><br><span class="line">      beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Register a default embedded value resolver if no bean post-processor</span></span><br><span class="line">  <span class="comment">// (such as a PropertyPlaceholderConfigurer bean) registered any before:</span></span><br><span class="line">  <span class="comment">// at this point, primarily for resolution in annotation attribute values.</span></span><br><span class="line">  <span class="comment">// 如果前面没有注册配置解析器，则注入配置解析器，主要用来处理配置文件的占位符等</span></span><br><span class="line">  <span class="keyword">if</span> (!beanFactory.hasEmbeddedValueResolver()) &#123;</span><br><span class="line">    beanFactory.addEmbeddedValueResolver(strVal -&gt; getEnvironment().resolvePlaceholders(strVal));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.</span></span><br><span class="line">  String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, <span class="keyword">false</span>, <span class="keyword">false</span>);</span><br><span class="line">  <span class="keyword">for</span> (String weaverAwareName : weaverAwareNames) &#123;</span><br><span class="line">    getBean(weaverAwareName);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Stop using the temporary ClassLoader for type matching.</span></span><br><span class="line">  <span class="comment">// 停止使用临时ClassLoader进行类型匹配</span></span><br><span class="line">  beanFactory.setTempClassLoader(<span class="keyword">null</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Allow for caching all bean definition metadata, not expecting further changes.</span></span><br><span class="line">  <span class="comment">// 冻结所有的Bean定义，在此后bean定义不会再被更改，因为在后面的方法就要开始根据bean定义创建bean实例了。</span></span><br><span class="line">  <span class="comment">// 所有的bean定义在此后修改将是无任何效果的</span></span><br><span class="line">  beanFactory.freezeConfiguration();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Instantiate all remaining (non-lazy-init) singletons.</span></span><br><span class="line">  <span class="comment">// 转到DefaultListableBeanFactory</span></span><br><span class="line">  <span class="comment">// 实例化剩余所有单例对象（除了加载单例）</span></span><br><span class="line">  beanFactory.preInstantiateSingletons();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>最关键、复杂的处理在<code>beanFactory.preInstantiateSingletons()</code>里面。</p>
<h4 id="preInstantiateSingletons"><a href="#preInstantiateSingletons" class="headerlink" title="preInstantiateSingletons()"></a>preInstantiateSingletons()</h4><p>进入单例对象实例处理代码。这个方法的作用就是遍历容器里面的所有的的<code>BeanDefinition</code>，根据bean定义信息做实例化，在bean的实例化过程中会执行一系列的bean后置处理器对bean做一下增强操作。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 实例化所有除了Spring内部的单例（懒加载的、抽象类、非单例的除外）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">preInstantiateSingletons</span><span class="params">()</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">    logger.trace(<span class="string">&quot;Pre-instantiating singletons in &quot;</span> + <span class="keyword">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Iterate over a copy to allow for init methods which in turn register new bean definitions.</span></span><br><span class="line">  <span class="comment">// While this may not be part of the regular factory bootstrap, it does otherwise work fine.</span></span><br><span class="line">  <span class="comment">// 创建BeanDefinitionName副本，用于后续遍历，以允许init等方法注册新的bean定义</span></span><br><span class="line">  List&lt;String&gt; beanNames = <span class="keyword">new</span> ArrayList&lt;&gt;(<span class="keyword">this</span>.beanDefinitionNames);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Trigger initialization of all non-lazy singleton beans...</span></span><br><span class="line">  <span class="comment">// 遍历所有的beanName，通过beanName获取到对应的bean实例，然后做初始化</span></span><br><span class="line">  <span class="keyword">for</span> (String beanName : beanNames) &#123;</span><br><span class="line">    <span class="comment">// 根据bean名称拿到bean定义</span></span><br><span class="line">    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">    <span class="comment">// bean定义非抽象类，是单例，非懒加载</span></span><br><span class="line">    <span class="keyword">if</span> (!bd.isAbstract() &amp;&amp; bd.isSingleton() &amp;&amp; !bd.isLazyInit()) &#123;</span><br><span class="line">      <span class="comment">// 判断是否是FactoryBean</span></span><br><span class="line">      <span class="comment">// Spring有两种类型的Bean，一种普通Bean，一种是工厂Bean即FactoryBean，FactoryBean和普通Bean不同，</span></span><br><span class="line">      <span class="comment">// 它返回的对象不是一个指定类型的对象，而是根据FactoryBean&lt;T&gt;.geteObject()返回对象，返回的对象就是T类型的，</span></span><br><span class="line">      <span class="comment">// 创建出来的对象是否为单例是根据Bean定义中的isSingleton属性决定的（默认是单例）</span></span><br><span class="line">      <span class="keyword">if</span> (isFactoryBean(beanName)) &#123;</span><br><span class="line">        <span class="comment">// 通过getBean(&amp;beanName)拿到是FactoryBean本身，FACTORY_BEAN_PREFIX=&amp;</span></span><br><span class="line">        <span class="comment">// 通过getBean(beanName)拿到的是FactoryBean创建的bean实例</span></span><br><span class="line">        <span class="comment">// 比如  MyInitializingBeanNoLazyAndBeanFactoryImpl implements FactoryBean&lt;Object&gt;</span></span><br><span class="line">        <span class="comment">// getBean(&amp;beanName)拿到的就是myInitializingBeanNoLazyAndBeanFactoryImpl这个bean实例。</span></span><br><span class="line">        <span class="comment">// getBean(beanName)拿到的是InitFromGetObjectMethodBean对象实例</span></span><br><span class="line">        Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);</span><br><span class="line">        <span class="keyword">if</span> (bean <span class="keyword">instanceof</span> FactoryBean) &#123;</span><br><span class="line">          <span class="keyword">final</span> FactoryBean&lt;?&gt; factory = (FactoryBean&lt;?&gt;) bean;</span><br><span class="line">          <span class="comment">// 判断bean是否需要急切初始化，实现了FactoryBean的类isEagerInit都是false，</span></span><br><span class="line">          <span class="comment">// 只有SmartFactoryBean的实现类可以控制这个属性值，但是这个接口是提供给Spring框架本身内部使用的不建议开发者使用</span></span><br><span class="line">          <span class="keyword">boolean</span> isEagerInit;</span><br><span class="line">          <span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span> &amp;&amp; factory <span class="keyword">instanceof</span> SmartFactoryBean) &#123;</span><br><span class="line">            isEagerInit = AccessController.doPrivileged((PrivilegedAction&lt;Boolean&gt;)</span><br><span class="line">                                                        ((SmartFactoryBean&lt;?&gt;) factory)::isEagerInit,</span><br><span class="line">                                                        getAccessControlContext());</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">else</span> &#123;</span><br><span class="line">            isEagerInit = (factory <span class="keyword">instanceof</span> SmartFactoryBean &amp;&amp;</span><br><span class="line">                           ((SmartFactoryBean&lt;?&gt;) factory).isEagerInit());</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">if</span> (isEagerInit) &#123;</span><br><span class="line">            <span class="comment">// 通过beanName获取bean实例</span></span><br><span class="line">            getBean(beanName);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 普通的bean直接通过beanName获取bean实例</span></span><br><span class="line">        getBean(beanName);  <span class="comment">// 转到AbstractBeanFactory</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// =========================================================================</span></span><br><span class="line">  <span class="comment">// 到此单例bean都已经实例化完毕，紧接着可以对实例对象做一些增强，通过BeanPostProcessor后置处理器增强</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// Trigger post-initialization callback for all applicable beans...</span></span><br><span class="line">  <span class="comment">// 判断是否有实现了SmartInittializingSingleton的实现类，通常是Spring内部的实现类，也是Spring提供的一个很重要的扩展点</span></span><br><span class="line">  <span class="comment">// @PostConstruct是最先被执行的，然后是InitializingBean，最后是SmartInitializingSingleton</span></span><br><span class="line">  <span class="keyword">for</span> (String beanName : beanNames) &#123;</span><br><span class="line">    Object singletonInstance = getSingleton(beanName);</span><br><span class="line">    <span class="keyword">if</span> (singletonInstance <span class="keyword">instanceof</span> SmartInitializingSingleton) &#123;</span><br><span class="line">      <span class="keyword">final</span> SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;</span><br><span class="line">      <span class="comment">// bean实例化后调用bean的afterSingletonsInstantiated方法，用户可以实现SmartInitializingSingleton接口，</span></span><br><span class="line">      <span class="comment">// 在bean实例化后做一些自定义的操作，比如重置实例的某些属性，但是要注意只能处理非懒加载的单例bean</span></span><br><span class="line">      <span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">        AccessController.doPrivileged((PrivilegedAction&lt;Object&gt;) () -&gt; &#123;</span><br><span class="line">          smartSingleton.afterSingletonsInstantiated();</span><br><span class="line">          <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        &#125;, getAccessControlContext());</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        smartSingleton.afterSingletonsInstantiated();</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>SmartInitializingSingleton</code>接口扩展点详细请看另外一片文章《Spring后置处理器》。</p>
<h5 id="getBean-beanName"><a href="#getBean-beanName" class="headerlink" title="getBean(beanName)"></a>getBean(beanName)</h5><p>bean实例化细节在<code>getBean(beanName)</code>中处理。这个方法最终会调用到他的实现方法<code>doGetBean()</code>中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Return an instance, which may be shared or independent, of the specified bean.</span></span><br><span class="line"><span class="comment">     * 返回指定beanName的实例</span></span><br><span class="line"><span class="comment">     * IoC容器初始化bean时通过调用的是getBean(String name)方法，所以，方法后面的三个参数是：null，null，false</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="meta">@SuppressWarnings(&quot;unchecked&quot;)</span></span><br><span class="line"><span class="keyword">protected</span> &lt;T&gt; <span class="function">T <span class="title">doGetBean</span><span class="params">(<span class="keyword">final</span> String name, <span class="meta">@Nullable</span> <span class="keyword">final</span> Class&lt;T&gt; requiredType,</span></span></span><br><span class="line"><span class="function"><span class="params">                          <span class="meta">@Nullable</span> <span class="keyword">final</span> Object[] args, <span class="keyword">boolean</span> typeCheckOnly)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">final</span> String beanName = transformedBeanName(name);</span><br><span class="line">  Object bean;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Eagerly check singleton cache for manually registered singletons.</span></span><br><span class="line">  <span class="comment">// 先获取早期的单例对象，先查缓存，如果这个bean已经创建过则直接返回（有可能还没做初始化属性赋值，是个半成品的实例，但是它的地址不会变了可以提前返回）</span></span><br><span class="line">  Object sharedInstance = getSingleton(beanName);</span><br><span class="line">  <span class="keyword">if</span> (sharedInstance != <span class="keyword">null</span> &amp;&amp; args == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      <span class="keyword">if</span> (isSingletonCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">        logger.trace(<span class="string">&quot;Returning eagerly cached instance of singleton bean &#x27;&quot;</span> + beanName +</span><br><span class="line">                     <span class="string">&quot;&#x27; that is not fully initialized yet - a consequence of a circular reference&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        logger.trace(<span class="string">&quot;Returning cached instance of singleton bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 获取bean实例对象，如果是工厂bean则设置bean的属性isFactoryBean为true</span></span><br><span class="line">    bean = getObjectForBeanInstance(sharedInstance, name, beanName, <span class="keyword">null</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 缓存中还没有beanName对应的实例</span></span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// Fail if we&#x27;re already creating this bean instance:</span></span><br><span class="line">    <span class="comment">// We&#x27;re assumably within a circular reference.</span></span><br><span class="line">    <span class="comment">// 如果是原型类型的bean直接抛异常</span></span><br><span class="line">    <span class="keyword">if</span> (isPrototypeCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Check if bean definition exists in this factory.</span></span><br><span class="line">    <span class="comment">// 检查是否存在父工厂，一般情况下开发者不会自定义工厂的实现，所以这里是一个null</span></span><br><span class="line">    BeanFactory parentBeanFactory = getParentBeanFactory();</span><br><span class="line">    <span class="keyword">if</span> (parentBeanFactory != <span class="keyword">null</span> &amp;&amp; !containsBeanDefinition(beanName)) &#123;</span><br><span class="line">      <span class="comment">// Not found -&gt; check parent.</span></span><br><span class="line">      String nameToLookup = originalBeanName(name);</span><br><span class="line">      <span class="keyword">if</span> (parentBeanFactory <span class="keyword">instanceof</span> AbstractBeanFactory) &#123;</span><br><span class="line">        <span class="keyword">return</span> ((AbstractBeanFactory) parentBeanFactory).doGetBean(</span><br><span class="line">          nameToLookup, requiredType, args, typeCheckOnly);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (args != <span class="keyword">null</span>) &#123;  <span class="comment">// 容器初始化调用getBean(String name)方法时args为null</span></span><br><span class="line">        <span class="comment">// Delegation to parent with explicit args.</span></span><br><span class="line">        <span class="keyword">return</span> (T) parentBeanFactory.getBean(nameToLookup, args);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (requiredType != <span class="keyword">null</span>) &#123;  <span class="comment">// 容器初始化调用getBean(String name)方法时requiredType为null</span></span><br><span class="line">        <span class="comment">// No args -&gt; delegate to standard getBean method.</span></span><br><span class="line">        <span class="keyword">return</span> parentBeanFactory.getBean(nameToLookup, requiredType);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> (T) parentBeanFactory.getBean(nameToLookup);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!typeCheckOnly) &#123;</span><br><span class="line">      <span class="comment">// 把创建好的bean实例标记成创建成功（就是把创建好的bean放到已经创建完成的数组里面）</span></span><br><span class="line">      markBeanAsCreated(beanName);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// 根据beanName获取bean定义信息</span></span><br><span class="line">      <span class="keyword">final</span> RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">      checkMergedBeanDefinition(mbd, beanName, args);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Guarantee initialization of beans that the current bean depends on.</span></span><br><span class="line">      <span class="comment">//  拿到beanName对应bean定义信息中的依赖集合，</span></span><br><span class="line">      <span class="comment">// 在实例化自己之前先实例化依赖的bean</span></span><br><span class="line">      String[] dependsOn = mbd.getDependsOn();</span><br><span class="line">      <span class="keyword">if</span> (dependsOn != <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (String dep : dependsOn) &#123;</span><br><span class="line">          <span class="keyword">if</span> (isDependent(beanName, dep)) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                                            <span class="string">&quot;Circular depends-on relationship between &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; and &#x27;&quot;</span> + dep + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="comment">// 将beanName和dep的依赖关系注册到缓存中</span></span><br><span class="line">          registerDependentBean(dep, beanName);</span><br><span class="line">          <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">// 获取beanName依赖的bean实例，如果dep对应是实例还没创建则创建dep对应的实例</span></span><br><span class="line">            <span class="comment">// 比如实例化beanA时发现依赖beanB则先初始化beanB，递归调用直到所有依赖都实例化</span></span><br><span class="line">            getBean(dep);</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">catch</span> (NoSuchBeanDefinitionException ex) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                                            <span class="string">&quot;&#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; depends on missing bean &#x27;&quot;</span> + dep + <span class="string">&quot;&#x27;&quot;</span>, ex);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Create bean instance.</span></span><br><span class="line">      <span class="comment">// beanName 对应的依赖bean创建完成后创建beanName实例</span></span><br><span class="line">      <span class="keyword">if</span> (mbd.isSingleton()) &#123;  <span class="comment">//  单例</span></span><br><span class="line">                    <span class="comment">/**</span></span><br><span class="line"><span class="comment">                     * getSingleton(String beanName, ObjectFactory&lt;?&gt; singletonFactory)方法</span></span><br><span class="line"><span class="comment">                     * 在父类FactoryBeanRegistrySupport的父类DefaultSingleBeanFactoryRegistry中做了实现</span></span><br><span class="line"><span class="comment">                     * ObjectFactory是一个bean工厂接口，这里是通过lambda表达式（匿名类）方式实现</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> DefaultSingletonBeanRegistry#getSingleton (String beanName, Object singletonObject)</span></span><br><span class="line"><span class="comment">                     */</span></span><br><span class="line">                    sharedInstance = getSingleton(beanName, () -&gt; &#123;</span><br><span class="line">                        <span class="keyword">try</span> &#123;</span><br><span class="line">                            <span class="comment">/**</span></span><br><span class="line"><span class="comment">                             * 创建单例对象，createBean方法由子类实现，</span></span><br><span class="line"><span class="comment">                             * <span class="doctag">@see</span> AbstractAutowireCapableBeanFactory#createBean (String beanName, RootBeanDefinition mbd, <span class="doctag">@Nullable</span> Object[] args)</span></span><br><span class="line"><span class="comment">                              */</span></span><br><span class="line">                            <span class="keyword">return</span> createBean(beanName, mbd, args);</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">                            destroySingleton(beanName);</span><br><span class="line">                            <span class="keyword">throw</span> ex;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;);</span><br><span class="line">                    <span class="comment">// 创建好之后直接从缓存中返回的单例对象</span></span><br><span class="line">                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (mbd.isPrototype()) &#123;  <span class="comment">// prototype类型实例</span></span><br><span class="line">        <span class="comment">// It&#x27;s a prototype -&gt; create a new instance.</span></span><br><span class="line">        <span class="comment">// 如果是prototype类型的bean，每次都新建一个实例</span></span><br><span class="line">        Object prototypeInstance = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">          beforePrototypeCreation(beanName);</span><br><span class="line">          prototypeInstance = createBean(beanName, mbd, args);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">finally</span> &#123;</span><br><span class="line">          afterPrototypeCreation(beanName);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 在createBean方法中创建好的单例对象已经设置到缓存中，这里是再从缓存中拿</span></span><br><span class="line">        <span class="comment">// 另外还有一个非常重要的功能是如果经过前面createBean方法还是没创建成功那么就会通过开发者实现的FactoryBean接口创建对象</span></span><br><span class="line">        <span class="comment">// 也就是说FactoryBean.getObject()方法是在这里被执行的。</span></span><br><span class="line">        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">else</span> &#123;  <span class="comment">// 非单例类型，非prototype类型，通常是一些web相关，比如request、session类型</span></span><br><span class="line">        <span class="comment">// 省略与主题不是很重要的代码</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">      cleanupAfterBeanCreationFailure(beanName);</span><br><span class="line">      <span class="keyword">throw</span> ex;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 省略与题主不是很相关的代码</span></span><br><span class="line">  </span><br><span class="line">  <span class="keyword">return</span> (T) bean;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>核心代码在<code>getSingleton(String beanName, ObjectFactory&lt;?&gt; singletonFactory)</code>方法和<code>getObjectForBeanInstance(sharedInstance, name, beanName, mbd)</code>方法的调用。下面分别介绍这两个方法。</p>
<p>第一个方法是在其父类中做了实现：<code>DefaultSingletonBeanRegistry.getSingleton(String beanName, Object singletonObject)</code>。</p>
<p>继续进入这个方法的逻辑。</p>
<h5 id="getSingleton-String-beanName-ObjectFactory-lt-gt-singletonFactory"><a href="#getSingleton-String-beanName-ObjectFactory-lt-gt-singletonFactory" class="headerlink" title="getSingleton(String beanName, ObjectFactory&lt;?&gt; singletonFactory)"></a>getSingleton(String beanName, ObjectFactory&lt;?&gt; singletonFactory)</h5><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">getSingleton</span><span class="params">(String beanName, ObjectFactory&lt;?&gt; singletonFactory)</span> </span>&#123;</span><br><span class="line">  Assert.notNull(beanName, <span class="string">&quot;Bean name must not be null&quot;</span>);</span><br><span class="line">  <span class="keyword">synchronized</span> (<span class="keyword">this</span>.singletonObjects) &#123;</span><br><span class="line">    <span class="comment">// 先从单例缓存中获取需要创建的对象，从单例缓存中获取到的是一个完整对象、已经经过初始化的bean对象。</span></span><br><span class="line">    <span class="comment">// 这个单例缓存也就是常说的一级缓存</span></span><br><span class="line">    Object singletonObject = <span class="keyword">this</span>.singletonObjects.get(beanName);</span><br><span class="line">    <span class="keyword">if</span> (singletonObject == <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="comment">// 省略与题主不是很相关的代码</span></span><br><span class="line">      </span><br><span class="line">      <span class="comment">// 在创建单例之前先设置一个标记，标记当前的bean正在创建</span></span><br><span class="line">      beforeSingletonCreation(beanName);</span><br><span class="line">      <span class="keyword">boolean</span> newSingleton = <span class="keyword">false</span>;</span><br><span class="line">      <span class="keyword">boolean</span> recordSuppressedExceptions = (<span class="keyword">this</span>.suppressedExceptions == <span class="keyword">null</span>);</span><br><span class="line">      <span class="keyword">if</span> (recordSuppressedExceptions) &#123;</span><br><span class="line">        <span class="keyword">this</span>.suppressedExceptions = <span class="keyword">new</span> LinkedHashSet&lt;&gt;();</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">                     * 通过单例工厂方式创建对象，这个接口的实现类就是参数传进来的匿名类。简单代码如下：</span></span><br><span class="line"><span class="comment">                     * getSingleton(beanName, () -&gt; AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args))</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> AbstractAutowireCapableBeanFactory#createBean (String beanName, RootBeanDefinition mbd, <span class="doctag">@Nullable</span> Object[] args)</span></span><br><span class="line"><span class="comment">                     */</span></span><br><span class="line">        singletonObject = singletonFactory.getObject();</span><br><span class="line">        newSingleton = <span class="keyword">true</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (IllegalStateException ex) &#123;</span><br><span class="line">        <span class="comment">// 省略与题主不是很相关的代码</span></span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (BeanCreationException ex) &#123;</span><br><span class="line">        <span class="comment">// 省略与题主不是很相关的代码</span></span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">finally</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (recordSuppressedExceptions) &#123;</span><br><span class="line">          <span class="keyword">this</span>.suppressedExceptions = <span class="keyword">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 清除当前bean正在创建的标记，表示这个beanName已经创建好单例对象</span></span><br><span class="line">        afterSingletonCreation(beanName);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">if</span> (newSingleton) &#123;</span><br><span class="line">        <span class="comment">// 单例对象创建完成之后设置到缓存里面，下次直接从缓存获取</span></span><br><span class="line">        addSingleton(beanName, singletonObject);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> singletonObject;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个方法的逻辑比较简单，主要做的事情就是1. 在创建前打标；2. 创建对象；3. 清理标记；4. 单例对象设置到缓存。最复杂的是第二步，第二步通过工厂接口创建对象，而工厂的接口是由子类<code>AbstractAutowireCapableBeanFactory</code>实现的。</p>
<h5 id="AbstractAutowireCapableBeanFactory-createBean-beanName-mbd-args"><a href="#AbstractAutowireCapableBeanFactory-createBean-beanName-mbd-args" class="headerlink" title="AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)"></a>AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)</h5><p>这个方法非常复杂，整个bean的实例化，然后是初始化，在初始化的过程中执行各种各样的后置处理器。当然也是Spring的一个非常重要的扩展点。</p>
<p>扩展接口如下：</p>
<ol>
<li><code>InstantiationAwareBeanPostProcessor</code>接口或者<code>InstantiationAwareBeanPostProcessorAdapter</code>，AOP实现就是通过此接口。</li>
<li><code>MergedBeanDefinitionPostProcessor</code>接口，在bean实例化之前，提供<strong>最后一个可以修改bean定义的机会</strong>。</li>
<li><code>SmartInstantiationAwareBeanPostProcessor</code>接口，在bean实例化前用于设置实例化的构造方法，<strong>此接口是Spring框架内部专用的接口，不建议开发者使用。</strong></li>
<li><code>BeanFactoryAware</code>/<code>ApplicationContextAware</code>/<code>BeanNameAware</code>接口，在bean实例化之后，填充属性时。</li>
<li><code>InitializingBean</code>接口或者是<code>@PostConstruct</code>注解的方法，在bean实例化之后，填充属性时。</li>
<li><code>DestructionAwareBeanPostProcessor</code>或者<code>DisposableBean</code>接口或者是<code>@PreDestory</code>注解声明的方法，这两个接口或注解是在bean销毁之前调用。</li>
<li></li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Central method of this class: creates a bean instance,</span></span><br><span class="line"><span class="comment">     * populates the bean instance, applies post-processors, etc.</span></span><br><span class="line"><span class="comment">     * 本类的核心方法：创建bean实例，填充bean实例属性，应用（执行）后置处理，</span></span><br><span class="line"><span class="comment">     * 详细处理逻辑在doCreateBean方法实现</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #doCreateBean</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">createBean</span><span class="params">(String beanName, RootBeanDefinition mbd, <span class="meta">@Nullable</span> Object[] args)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> BeanCreationException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">    logger.trace(<span class="string">&quot;Creating instance of bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  RootBeanDefinition mbdToUse = mbd;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Make sure bean class is actually resolved at this point, and</span></span><br><span class="line">  <span class="comment">// clone the bean definition in case of a dynamically resolved Class</span></span><br><span class="line">  <span class="comment">// which cannot be stored in the shared merged bean definition.</span></span><br><span class="line">  <span class="comment">// 通过Class.forName(bean)方法获取实例，合并bean定义</span></span><br><span class="line">  Class&lt;?&gt; resolvedClass = resolveBeanClass(mbd, beanName);</span><br><span class="line">  <span class="keyword">if</span> (resolvedClass != <span class="keyword">null</span> &amp;&amp; !mbd.hasBeanClass() &amp;&amp; mbd.getBeanClassName() != <span class="keyword">null</span>) &#123;</span><br><span class="line">    mbdToUse = <span class="keyword">new</span> RootBeanDefinition(mbd);</span><br><span class="line">    mbdToUse.setBeanClass(resolvedClass);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Prepare method overrides.</span></span><br><span class="line">  <span class="comment">// 设置重写属性值：setOverloaded(false)</span></span><br><span class="line">  <span class="comment">// @LookUp注解就是在这里实现的</span></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    mbdToUse.prepareMethodOverrides();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (BeanDefinitionValidationException ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(mbdToUse.getResourceDescription(),</span><br><span class="line">                                           beanName, <span class="string">&quot;Validation of method overrides failed&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.</span></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 执行后置处理器</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor 接口实现类，</span></span><br><span class="line"><span class="comment">             * 给一个机会返回代理对象而不是目标bean实例本身，如果是AOP类就会在这里返回了，比如用<span class="doctag">@Aspect</span>注释的类</span></span><br><span class="line"><span class="comment">             * 此接口通常是Spring框架内部使用，这个接口的功能非常强大，使用起来难度大，主要是它继承了很多后置处理接口，导致里面的方法很多（一共有6个方法需要实现）。</span></span><br><span class="line"><span class="comment">             * 如果开发者也想使用此接口的功能推荐使用它的抽象实现InstantiationAwareBeanPostProcessorAdapter。继承此类重写其中你需要的方法即可，</span></span><br><span class="line"><span class="comment">             * 这个抽象类做了一些默认实现不需要你实现9个方法，重写你要的就行了。</span></span><br><span class="line"><span class="comment">             * 注意：如果这里返回了代理对象，则直接结束当前方法返回，不继续往下执行doCreateBean创建普通实例，doCreateBean里面进行的属性填充后置处理器也不会执行。</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> #resolveBeforeInstantiation</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);</span><br><span class="line">    <span class="keyword">if</span> (bean != <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbdToUse.getResourceDescription(), beanName,</span><br><span class="line">                                    <span class="string">&quot;BeanPostProcessor before instantiation of bean failed&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// 根据BeanDefinition创建bean，并且对创建好的bean执行框架定义的+用户定义的各种后置处理器对bean增强。</span></span><br><span class="line">    Object beanInstance = doCreateBean(beanName, mbdToUse, args);</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;Finished creating instance of bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> beanInstance;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (BeanCreationException | ImplicitlyAppearedSingletonException ex) &#123;</span><br><span class="line">    <span class="comment">// A previously detected exception with proper bean creation context already,</span></span><br><span class="line">    <span class="comment">// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.</span></span><br><span class="line">    <span class="keyword">throw</span> ex;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">      mbdToUse.getResourceDescription(), beanName, <span class="string">&quot;Unexpected exception during bean creation&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>核心方法有两个，一个是<code>resolveBeforeInstantiation(beanName, mbdToUse)</code>，一个是<code>doCreateBean(beanName, mbdToUse, args)</code>。</p>
<p>第一个方法用于执行后置处理器。AOP创建的代理对象就是在此方法中返回的。</p>
<p>第二个方法用于创建普通的bean对象。</p>
<h6 id="resolveBeforeInstantiation-beanName-mbdToUse"><a href="#resolveBeforeInstantiation-beanName-mbdToUse" class="headerlink" title="resolveBeforeInstantiation(beanName, mbdToUse)"></a>resolveBeforeInstantiation(beanName, mbdToUse)</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Apply before-instantiation post-processors, resolving whether there is a</span></span><br><span class="line"><span class="comment">     * before-instantiation shortcut for the specified bean.</span></span><br><span class="line"><span class="comment">     * 应用实例化之前的后处理器，如果容器中存在InstantiationAwareBeanPostProcessor接口的实现类</span></span><br><span class="line"><span class="comment">     * 则执行容器中所有此接口实现类的postProcessBeforeInstantiation()方法和postProcessAfterInitialization()方法</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> beanName the name of the bean</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> mbd the bean definition for the bean</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> the shortcut-determined bean instance, or &#123;<span class="doctag">@code</span> null&#125; if none</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@see</span> #createBean(String, RootBeanDefinition, Object[]) </span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">resolveBeforeInstantiation</span><span class="params">(String beanName, RootBeanDefinition mbd)</span> </span>&#123;</span><br><span class="line">  Object bean = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) &#123;</span><br><span class="line">    <span class="comment">// Make sure bean class is actually resolved at this point.</span></span><br><span class="line">    <span class="comment">// 判断是否有InstantiationAwareBeanPostProcessor实现类</span></span><br><span class="line">    <span class="keyword">if</span> (!mbd.isSynthetic() &amp;&amp; hasInstantiationAwareBeanPostProcessors()) &#123;</span><br><span class="line">      Class&lt;?&gt; targetType = determineTargetType(beanName, mbd);</span><br><span class="line">      <span class="keyword">if</span> (targetType != <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">                     * 执行接口的postProcessBeforeInstantiation()方法</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> #applyBeanPostProcessorsBeforeInstantiation</span></span><br><span class="line"><span class="comment">                     */</span></span><br><span class="line">        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);</span><br><span class="line">        <span class="comment">// 返回值不为空说明返回的是一个代理对象。再对代理对象执行postProcessorsAfterInitialization()方法</span></span><br><span class="line">        <span class="keyword">if</span> (bean != <span class="keyword">null</span>) &#123;</span><br><span class="line">          bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 设置bean定义的beforeInstantiationResolved属性值（程序包可见的字段，指示实例化之前的后处理器已启动）</span></span><br><span class="line">    mbd.beforeInstantiationResolved = (bean != <span class="keyword">null</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> bean;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行接口的<code>postProcessorBeforeInstantiation()</code>方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">applyBeanPostProcessorsBeforeInstantiation</span><span class="params">(Class&lt;?&gt; beanClass, String beanName)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (BeanPostProcessor bp : getBeanPostProcessors()) &#123;</span><br><span class="line">    <span class="keyword">if</span> (bp <span class="keyword">instanceof</span> InstantiationAwareBeanPostProcessor) &#123;</span><br><span class="line">      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;</span><br><span class="line">      <span class="comment">/**</span></span><br><span class="line"><span class="comment">                 * 它在目标对象实例化之前调用，该方法的返回值类型是Object，我们可以返回任何类型的值。</span></span><br><span class="line"><span class="comment">                 * 由于这个时候目标对象还未实例化，所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。</span></span><br><span class="line"><span class="comment">                 * 如果该方法的返回值代替原本该生成的目标对象，后续只有postProcessAfterInitialization方法会调用，</span></span><br><span class="line"><span class="comment">                 * InstantiationAwareBeanPostProcessor接口的其它方法不再调用；</span></span><br><span class="line"><span class="comment">                 * 否则按照正常的流程走，框架内部实现类有如下这些：</span></span><br><span class="line"><span class="comment">                 * <span class="doctag">@see</span> InstantiationAwareBeanPostProcessorAdapter</span></span><br><span class="line"><span class="comment">                 */</span></span><br><span class="line">      Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);</span><br><span class="line">      <span class="comment">// 只要有一个result不为null；后面的所有 后置处理器的方法就不执行了，直接返回(所以执行顺序很重要)</span></span><br><span class="line">      <span class="keyword">if</span> (result != <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行接口的<code>postProcessorAfterInstantiation()</code>方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Object <span class="title">applyBeanPostProcessorsAfterInitialization</span><span class="params">(Object existingBean, String beanName)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">  <span class="comment">// 代理对象，处理代理对象的postProcessAfterInitialization()方法</span></span><br><span class="line">  Object result = existingBean;</span><br><span class="line">  <span class="keyword">for</span> (BeanPostProcessor processor : getBeanPostProcessors()) &#123;</span><br><span class="line">    Object current = processor.postProcessAfterInitialization(result, beanName);</span><br><span class="line">    <span class="keyword">if</span> (current == <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">    result = current;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h6 id="AbstractBeanFactory-doCreateBean-beanName-mbdToUse-args"><a href="#AbstractBeanFactory-doCreateBean-beanName-mbdToUse-args" class="headerlink" title="AbstractBeanFactory.doCreateBean(beanName, mbdToUse, args)"></a>AbstractBeanFactory.doCreateBean(beanName, mbdToUse, args)</h6><p>这个方法主要完成如下事项：</p>
<ol>
<li>先从缓存获取bean实例，如果存在直接返回</li>
<li>不在缓存中则通过<code>doCreateBean()</code>方法创建。判断bean定义是单例，还是其他Scope<ol>
<li>如是单例，则先创建bean依赖的bean。</li>
<li>创建bean本身</li>
<li>执行后置处理器<code>InstantiationAwareBeanPostProcessor</code>提供一个机会可以返回代理对象（AOP实现的代码位置）</li>
<li>通过底层反射<code>newInstance()</code>方法创建对象</li>
<li>执行后置处理器<code>AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor</code>后置处理器扫描<code>@Autowired</code>，<code>@Resource</code>，<code>@Value</code>注解的属并设置到缓存中，这里并不是真正实现注入。</li>
<li>执行后置处理器<code>SmartInstantiationAwareBeanPostProcessor</code>的<code>getEarlyBeanReference()</code>方法尝试获取一个早期的引用，并设置到单例工厂缓存中。</li>
<li>执行后置处理器<code>InstantiationAwareBeanPostProcessor</code>对实例化后初始化前的bean做一下扩展操作。</li>
<li>执行后置处理器<code>AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor</code>后置处理器注入定义为<code>@Autowired</code>，<code>@Resource</code>，<code>@Value</code>的属</li>
<li>对<code>&lt;property&gt;</code>标签进行属性注入。</li>
<li>执行Aware接口 ，包括BeanFactoryAware，BeanClassLoaderAware，BeanNameAware</li>
<li>执行各种初始化回调方法，包括<code>@PostConstruct</code>注解定义的方法、<code>InitializingBean</code>接口的<code>afterPropertiesSet()</code>方法、<code>@Bean(initMethod=&quot;bean中自定义的方法名&quot;)</code>注解中自定义的初始化方法</li>
<li>循环依赖检查</li>
<li>注册（只是注册，并不是执行，手动关闭容器的时候才会执行）各种bean的销毁回调方法，包括<code>DispoableBean</code>接口的<code>destory()</code>方法、<code>@Bean(destoryMethod=&quot;bean中自定义的方法名&quot;)</code>自定义的方法、<code>@PreDestory</code>注解定义的方法、把容器中<code>DestructionAwareBeanPostProcessor</code>的实现类注入到属性<code>this.beanPostProcessors</code>上。</li>
<li>把创建好的对象设置到缓存中。</li>
</ol>
</li>
<li>如果Scope不单例，同样是按照上面第二点的步骤创建对象，唯一不同的是不会把对象设置到缓存中。每次都是创建一个新的对象</li>
</ol>
<p>详细源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">protected</span> &lt;T&gt; <span class="function">T <span class="title">doGetBean</span><span class="params">(<span class="keyword">final</span> String name, <span class="meta">@Nullable</span> <span class="keyword">final</span> Class&lt;T&gt; requiredType,</span></span></span><br><span class="line"><span class="function"><span class="params">                          <span class="meta">@Nullable</span> <span class="keyword">final</span> Object[] args, <span class="keyword">boolean</span> typeCheckOnly)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">final</span> String beanName = transformedBeanName(name);</span><br><span class="line">  Object bean;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Eagerly check singleton cache for manually registered singletons.</span></span><br><span class="line">  <span class="comment">// 先获取早期的单例对象，先查缓存，如果这个bean已经创建过则直接返回（有可能还没做初始化属性赋值，是个半成品的实例，但是它的地址不会变了可以提前返回）</span></span><br><span class="line">  Object sharedInstance = getSingleton(beanName);</span><br><span class="line">  <span class="keyword">if</span> (sharedInstance != <span class="keyword">null</span> &amp;&amp; args == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      <span class="keyword">if</span> (isSingletonCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">        logger.trace(<span class="string">&quot;Returning eagerly cached instance of singleton bean &#x27;&quot;</span> + beanName +</span><br><span class="line">                     <span class="string">&quot;&#x27; that is not fully initialized yet - a consequence of a circular reference&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        logger.trace(<span class="string">&quot;Returning cached instance of singleton bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 获取bean实例对象，如果是工厂bean则设置bean的属性isFactoryBean为true</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    bean = getObjectForBeanInstance(sharedInstance, name, beanName, <span class="keyword">null</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 缓存中还没有beanName对应的实例</span></span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// Fail if we&#x27;re already creating this bean instance:</span></span><br><span class="line">    <span class="comment">// We&#x27;re assumably within a circular reference.</span></span><br><span class="line">    <span class="comment">// 如果是原型类型的bean直接抛异常</span></span><br><span class="line">    <span class="keyword">if</span> (isPrototypeCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Check if bean definition exists in this factory.</span></span><br><span class="line">    <span class="comment">// 检查是否存在父工厂，一般情况下开发者不会自定义工厂的实现，所以这里是一个null</span></span><br><span class="line">    BeanFactory parentBeanFactory = getParentBeanFactory();</span><br><span class="line">    <span class="keyword">if</span> (parentBeanFactory != <span class="keyword">null</span> &amp;&amp; !containsBeanDefinition(beanName)) &#123;</span><br><span class="line">      <span class="comment">// Not found -&gt; check parent.</span></span><br><span class="line">      String nameToLookup = originalBeanName(name);</span><br><span class="line">      <span class="keyword">if</span> (parentBeanFactory <span class="keyword">instanceof</span> AbstractBeanFactory) &#123;</span><br><span class="line">        <span class="keyword">return</span> ((AbstractBeanFactory) parentBeanFactory).doGetBean(</span><br><span class="line">          nameToLookup, requiredType, args, typeCheckOnly);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (args != <span class="keyword">null</span>) &#123;  <span class="comment">// 容器初始化调用getBean(String name)方法时args为null</span></span><br><span class="line">        <span class="comment">// Delegation to parent with explicit args.</span></span><br><span class="line">        <span class="keyword">return</span> (T) parentBeanFactory.getBean(nameToLookup, args);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (requiredType != <span class="keyword">null</span>) &#123;  <span class="comment">// 容器初始化调用getBean(String name)方法时requiredType为null</span></span><br><span class="line">        <span class="comment">// No args -&gt; delegate to standard getBean method.</span></span><br><span class="line">        <span class="keyword">return</span> parentBeanFactory.getBean(nameToLookup, requiredType);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> (T) parentBeanFactory.getBean(nameToLookup);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!typeCheckOnly) &#123;</span><br><span class="line">      <span class="comment">// 把创建好的bean实例标记成创建成功（就是把创建好的bean放到已经创建完成的数组里面）</span></span><br><span class="line">      markBeanAsCreated(beanName);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// 根据beanName获取bean定义信息</span></span><br><span class="line">      <span class="keyword">final</span> RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">      checkMergedBeanDefinition(mbd, beanName, args);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Guarantee initialization of beans that the current bean depends on.</span></span><br><span class="line">      <span class="comment">//  拿到beanName对应bean定义信息中的依赖集合，</span></span><br><span class="line">      <span class="comment">// 在实例化自己之前先实例化依赖的bean</span></span><br><span class="line">      String[] dependsOn = mbd.getDependsOn();</span><br><span class="line">      <span class="keyword">if</span> (dependsOn != <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (String dep : dependsOn) &#123;</span><br><span class="line">          <span class="keyword">if</span> (isDependent(beanName, dep)) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                                            <span class="string">&quot;Circular depends-on relationship between &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; and &#x27;&quot;</span> + dep + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="comment">// 将beanName和dep的依赖关系注册到缓存中</span></span><br><span class="line">          registerDependentBean(dep, beanName);</span><br><span class="line">          <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">// 获取beanName依赖的bean实例，如果dep对应是实例还没创建则创建dep对应的实例</span></span><br><span class="line">            <span class="comment">// 比如实例化beanA时发现依赖beanB则先初始化beanB，递归调用直到所有依赖都实例化</span></span><br><span class="line">            getBean(dep);</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">catch</span> (NoSuchBeanDefinitionException ex) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                                            <span class="string">&quot;&#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; depends on missing bean &#x27;&quot;</span> + dep + <span class="string">&quot;&#x27;&quot;</span>, ex);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Create bean instance.</span></span><br><span class="line">      <span class="comment">// beanName 对应的依赖bean创建完成后创建beanName实例</span></span><br><span class="line">      <span class="keyword">if</span> (mbd.isSingleton()) &#123;  <span class="comment">//  单例</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">                     * getSingleton(String beanName, ObjectFactory&lt;?&gt; singletonFactory)方法</span></span><br><span class="line"><span class="comment">                     * 在父类FactoryBeanRegistrySupport的父类DefaultSingleBeanFactoryRegistry中做了实现</span></span><br><span class="line"><span class="comment">                     * ObjectFactory是一个bean工厂接口，这里是通过lambda表达式（匿名类）方式实现</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> DefaultSingletonBeanRegistry#getSingleton (String beanName, Object singletonObject)</span></span><br><span class="line"><span class="comment">                     */</span></span><br><span class="line">        sharedInstance = getSingleton(beanName, () -&gt; &#123;</span><br><span class="line">          <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">/**</span></span><br><span class="line"><span class="comment">                             * 创建单例对象，createBean方法由子类实现，</span></span><br><span class="line"><span class="comment">                             * <span class="doctag">@see</span> AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[]) </span></span><br><span class="line"><span class="comment">                              */</span></span><br><span class="line">            <span class="keyword">return</span> createBean(beanName, mbd, args);</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">            <span class="comment">// Explicitly remove instance from singleton cache: It might have been put there</span></span><br><span class="line">            <span class="comment">// eagerly by the creation process, to allow for circular reference resolution.</span></span><br><span class="line">            <span class="comment">// Also remove any beans that received a temporary reference to the bean.</span></span><br><span class="line">            destroySingleton(beanName);</span><br><span class="line">            <span class="keyword">throw</span> ex;</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="comment">// 如果经过前面createBean方法还是没创建成功那么就会通过开发者实现的FactoryBean接口创建对象</span></span><br><span class="line">        <span class="comment">// 也就是说FactoryBean.getObject()方法是在这里被执行的。</span></span><br><span class="line">        <span class="comment">// 通过FactoryBean创建的实例不会执行初始化回调。不会执行XxxAware接口</span></span><br><span class="line">        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="comment">// prototype类型实例</span></span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (mbd.isPrototype()) &#123;</span><br><span class="line">        <span class="comment">// It&#x27;s a prototype -&gt; create a new instance.</span></span><br><span class="line">        <span class="comment">// 如果是prototype类型的bean，每次都新建一个实例</span></span><br><span class="line">        Object prototypeInstance = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">          beforePrototypeCreation(beanName);</span><br><span class="line">          prototypeInstance = createBean(beanName, mbd, args);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">finally</span> &#123;</span><br><span class="line">          afterPrototypeCreation(beanName);</span><br><span class="line">        &#125;</span><br><span class="line">        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="comment">// 非单例类型，非prototype类型，通常是一些web相关，比如request、session类型</span></span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        String scopeName = mbd.getScope();</span><br><span class="line">        <span class="keyword">final</span> Scope scope = <span class="keyword">this</span>.scopes.get(scopeName);</span><br><span class="line">        <span class="keyword">if</span> (scope == <span class="keyword">null</span>) &#123;</span><br><span class="line">          <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">&quot;No Scope registered for scope name &#x27;&quot;</span> + scopeName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">          Object scopedInstance = scope.get(beanName, () -&gt; &#123;</span><br><span class="line">            beforePrototypeCreation(beanName);</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">              <span class="keyword">return</span> createBean(beanName, mbd, args);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">finally</span> &#123;</span><br><span class="line">              afterPrototypeCreation(beanName);</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;);</span><br><span class="line">          bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">catch</span> (IllegalStateException ex) &#123;</span><br><span class="line">          <span class="comment">// 省略</span></span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">      <span class="comment">// 省略</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Check if required type matches the type of the actual bean instance.</span></span><br><span class="line">  <span class="comment">// 检查bean是否有必须的类型转换</span></span><br><span class="line">  <span class="keyword">if</span> (requiredType != <span class="keyword">null</span> &amp;&amp; !requiredType.isInstance(bean)) &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);</span><br><span class="line">      <span class="keyword">if</span> (convertedBean == <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> convertedBean;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">catch</span> (TypeMismatchException ex) &#123;</span><br><span class="line">      <span class="comment">// 省略</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> (T) bean;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>下面分别介绍<code>doCreatBean()</code>方法中调用的核心方法。</p>
<h6 id="AbstractAutowireCapableBeanFactory-createBean"><a href="#AbstractAutowireCapableBeanFactory-createBean" class="headerlink" title="AbstractAutowireCapableBeanFactory#createBean"></a>AbstractAutowireCapableBeanFactory#createBean</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">createBean</span><span class="params">(String beanName, RootBeanDefinition mbd, <span class="meta">@Nullable</span> Object[] args)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> BeanCreationException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">    logger.trace(<span class="string">&quot;Creating instance of bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  RootBeanDefinition mbdToUse = mbd;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Make sure bean class is actually resolved at this point, and</span></span><br><span class="line">  <span class="comment">// clone the bean definition in case of a dynamically resolved Class</span></span><br><span class="line">  <span class="comment">// which cannot be stored in the shared merged bean definition.</span></span><br><span class="line">  <span class="comment">// 通过Class.forName(bean)方法获取实例，合并bean定义</span></span><br><span class="line">  Class&lt;?&gt; resolvedClass = resolveBeanClass(mbd, beanName);</span><br><span class="line">  <span class="keyword">if</span> (resolvedClass != <span class="keyword">null</span> &amp;&amp; !mbd.hasBeanClass() &amp;&amp; mbd.getBeanClassName() != <span class="keyword">null</span>) &#123;</span><br><span class="line">    mbdToUse = <span class="keyword">new</span> RootBeanDefinition(mbd);</span><br><span class="line">    mbdToUse.setBeanClass(resolvedClass);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Prepare method overrides.</span></span><br><span class="line">  <span class="comment">// 设置重写属性值：setOverloaded(false)</span></span><br><span class="line">  <span class="comment">// @LookUp注解就是在这里实现的</span></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    mbdToUse.prepareMethodOverrides();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (BeanDefinitionValidationException ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(mbdToUse.getResourceDescription(),</span><br><span class="line">                                           beanName, <span class="string">&quot;Validation of method overrides failed&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.</span></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 执行后置处理器</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor 接口实现类，</span></span><br><span class="line"><span class="comment">             * 给一个机会返回代理对象而不是目标bean实例本身，如果是AOP类就会在这里返回了，比如用<span class="doctag">@Aspect</span>注释的类</span></span><br><span class="line"><span class="comment">             * 此接口通常是Spring框架内部使用，这个接口的功能非常强大，使用起来难度大，主要是它继承了很多后置处理接口，导致里面的方法很多（一共有6个方法需要实现）。</span></span><br><span class="line"><span class="comment">             * 如果开发者也想使用此接口的功能推荐使用它的抽象实现InstantiationAwareBeanPostProcessorAdapter。继承此类重写其中你需要的方法即可，</span></span><br><span class="line"><span class="comment">             * 这个抽象类做了一些默认实现不需要你实现9个方法，重写你要的就行了。</span></span><br><span class="line"><span class="comment">             * 注意：如果这里返回了代理对象，则直接结束当前方法返回，不继续往下执行doCreateBean创建普通实例，doCreateBean里面进行的属性填充后置处理器也不会执行。</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> #resolveBeforeInstantiation</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);</span><br><span class="line">    <span class="keyword">if</span> (bean != <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbdToUse.getResourceDescription(), beanName,</span><br><span class="line">                                    <span class="string">&quot;BeanPostProcessor before instantiation of bean failed&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// 根据BeanDefinition创建bean，并且对创建好的bean执行框架定义的+用户定义的各种后置处理器对bean增强。</span></span><br><span class="line">    <span class="comment">// 同时也会进行属性的填充，执行初始化回调方法，执行XxxAware接口</span></span><br><span class="line">    Object beanInstance = doCreateBean(beanName, mbdToUse, args);</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;Finished creating instance of bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 回到调用处：</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> AbstractBeanFactory#doGetBean(String, Class, Object[], boolean)</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    <span class="keyword">return</span> beanInstance;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (BeanCreationException | ImplicitlyAppearedSingletonException ex) &#123;</span><br><span class="line">    <span class="comment">// A previously detected exception with proper bean creation context already,</span></span><br><span class="line">    <span class="comment">// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.</span></span><br><span class="line">    <span class="keyword">throw</span> ex;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">      mbdToUse.getResourceDescription(), beanName, <span class="string">&quot;Unexpected exception during bean creation&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个方法完成两个事情，一是提供一个创建代理的机会，二，不创建代理的情况调用<code>doCreateBean(beanName, mbdToUse,args)</code>方法创建对象。</p>
<h6 id="doCreateBean-beanName-mbdToUse-args"><a href="#doCreateBean-beanName-mbdToUse-args" class="headerlink" title="doCreateBean(beanName, mbdToUse, args);"></a>doCreateBean(beanName, mbdToUse, args);</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">doCreateBean</span><span class="params">(<span class="keyword">final</span> String beanName, <span class="keyword">final</span> RootBeanDefinition mbd, <span class="keyword">final</span> <span class="meta">@Nullable</span> Object[] args)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> BeanCreationException </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Instantiate the bean.</span></span><br><span class="line">  BeanWrapper instanceWrapper = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (mbd.isSingleton()) &#123;</span><br><span class="line">    <span class="comment">// 从缓存中查询，如果是bean定义是一个bean工厂实例可以直接拿到。</span></span><br><span class="line">    instanceWrapper = <span class="keyword">this</span>.factoryBeanInstanceCache.remove(beanName);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (instanceWrapper == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="comment">// 普通bean，根据bean定义创建bean实例，并包装成BeanWrapper返回</span></span><br><span class="line">    instanceWrapper = createBeanInstance(beanName, mbd, args);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 获取经过jdk1.8的Optional类包装过的非空对象</span></span><br><span class="line">  <span class="keyword">final</span> Object bean = instanceWrapper.getWrappedInstance();</span><br><span class="line">  <span class="comment">// 获取bean的class类型</span></span><br><span class="line">  Class&lt;?&gt; beanType = instanceWrapper.getWrappedClass();</span><br><span class="line">  <span class="keyword">if</span> (beanType != NullBean.class) &#123;</span><br><span class="line">    mbd.resolvedTargetType = beanType;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Allow post-processors to modify the merged bean definition.</span></span><br><span class="line">  <span class="keyword">synchronized</span> (mbd.postProcessingLock) &#123;</span><br><span class="line">    <span class="keyword">if</span> (!mbd.postProcessed) &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">// 执行后置处理器接口MergedBeanDefinitionPostProcessor，bean实例化之后，就可以通过反射获取到类或者属性上的注释信息</span></span><br><span class="line">        <span class="comment">// 处理@Resource、@Autowired、@Value注解的定义信息，并把这些注解的定义信息放在缓存中。待后续属性填充的时候使用。</span></span><br><span class="line">        <span class="comment">// 如果有则吧注解信息转换成AutowiredFieldElement对象或者AutowiredMethodElement对象或者ResourceElement对象</span></span><br><span class="line">        <span class="comment">// 实现类有：AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等</span></span><br><span class="line">        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                                        <span class="string">&quot;Post-processing of merged bean definition failed&quot;</span>, ex);</span><br><span class="line">      &#125;</span><br><span class="line">      mbd.postProcessed = <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Eagerly cache singletons to be able to resolve circular references</span></span><br><span class="line">  <span class="comment">// even when triggered by lifecycle interfaces like BeanFactoryAware.</span></span><br><span class="line">  <span class="comment">// 单例bean &amp;&amp; 允许循环依赖 &amp;&amp; bean正在被创建</span></span><br><span class="line">  <span class="keyword">boolean</span> earlySingletonExposure = (mbd.isSingleton() &amp;&amp; <span class="keyword">this</span>.allowCircularReferences &amp;&amp;</span><br><span class="line">                                    isSingletonCurrentlyInCreation(beanName));</span><br><span class="line">  <span class="keyword">if</span> (earlySingletonExposure) &#123;</span><br><span class="line">    <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;Eagerly caching bean &#x27;&quot;</span> + beanName +</span><br><span class="line">                   <span class="string">&quot;&#x27; to allow for resolving potential circular references&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 执行后置处理器SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法尝试获取一个早期的引用。</span></span><br><span class="line"><span class="comment">             * 并加入的单例工厂缓存中</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> DefaultSingletonBeanRegistry#addSingletonFactory(String, ObjectFactory)</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> #getEarlyBeanReference</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    addSingletonFactory(beanName, () -&gt; getEarlyBeanReference(beanName, mbd, bean));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Initialize the bean instance.</span></span><br><span class="line">  <span class="comment">// 初始化bean实例，填充属性，注入依赖（@Autowired，@Resource，@Value）注解的属性</span></span><br><span class="line">  Object exposedObject = bean;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    populateBean(beanName, mbd, instanceWrapper);</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             执行bean的初始化回调方法以及执行后置处理器的初始化方法，包括：</span></span><br><span class="line"><span class="comment">            一，执行Aware接口 ，包括BeanFactoryAware，BeanClassLoaderAware，BeanNameAware</span></span><br><span class="line"><span class="comment">                注意：ApplicationContext的注入是在另外一个后置处理器ApplicationContextAwareProcessor中执行。</span></span><br><span class="line"><span class="comment">              二，执行bean初始化回调，包括：</span></span><br><span class="line"><span class="comment">                0. 执行初始化回调BeanPostProcessor.postProcessBeforeInitialization()方法</span></span><br><span class="line"><span class="comment">                1. 执行初始化回调<span class="doctag">@PostConstruct</span>注解定义的方法</span></span><br><span class="line"><span class="comment">                 2. 执行初始化回调InitializingBean.afterPropertiesSet()方法</span></span><br><span class="line"><span class="comment">                3. 执行初始化回调<span class="doctag">@Bean</span>(initMethod = &quot;beanInit&quot;)定义的初始化方法beanInit()</span></span><br><span class="line"><span class="comment">                 4. 执行初始化回调BeanPostProcessor.postProcessAfterInitialization()方法</span></span><br><span class="line"><span class="comment">                5. 执行初始化回调SmartInitializingSingleton.afterSingletonsInstantiated()方法</span></span><br><span class="line"><span class="comment">                按照上述执行顺序执行</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    exposedObject = initializeBean(beanName, exposedObject, mbd);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    <span class="keyword">if</span> (ex <span class="keyword">instanceof</span> BeanCreationException &amp;&amp; beanName.equals(((BeanCreationException) ex).getBeanName())) &#123;</span><br><span class="line">      <span class="keyword">throw</span> (BeanCreationException) ex;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">        mbd.getResourceDescription(), beanName, <span class="string">&quot;Initialization of bean failed&quot;</span>, ex);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 循环依赖检查</span></span><br><span class="line">  <span class="keyword">if</span> (earlySingletonExposure) &#123;</span><br><span class="line">    Object earlySingletonReference = getSingleton(beanName, <span class="keyword">false</span>);</span><br><span class="line">    <span class="keyword">if</span> (earlySingletonReference != <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span> (exposedObject == bean) &#123;</span><br><span class="line">        exposedObject = earlySingletonReference;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (!<span class="keyword">this</span>.allowRawInjectionDespiteWrapping &amp;&amp; hasDependentBean(beanName)) &#123;</span><br><span class="line">        String[] dependentBeans = getDependentBeans(beanName);</span><br><span class="line">        Set&lt;String&gt; actualDependentBeans = <span class="keyword">new</span> LinkedHashSet&lt;&gt;(dependentBeans.length);</span><br><span class="line">        <span class="keyword">for</span> (String dependentBean : dependentBeans) &#123;</span><br><span class="line">          <span class="keyword">if</span> (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) &#123;</span><br><span class="line">            actualDependentBeans.add(dependentBean);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!actualDependentBeans.isEmpty()) &#123;</span><br><span class="line">          <span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName,</span><br><span class="line">                                                     <span class="string">&quot;Bean with name &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; has been injected into other beans [&quot;</span> +</span><br><span class="line">                                                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +</span><br><span class="line">                                                     <span class="string">&quot;] in its raw version as part of a circular reference, but has eventually been &quot;</span> +</span><br><span class="line">                                                     <span class="string">&quot;wrapped. This means that said other beans do not use the final version of the &quot;</span> +</span><br><span class="line">                                                     <span class="string">&quot;bean. This is often the result of over-eager type matching - consider using &quot;</span> +</span><br><span class="line">                                                     <span class="string">&quot;&#x27;getBeanNamesOfType&#x27; with the &#x27;allowEagerInit&#x27; flag turned off, for example.&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Register bean as disposable.</span></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 注册bean销毁回调方法，这个方法和前面的initializeBean()方法是对应的。通常情况下初始化方法和销毁方法是同时出现的。</span></span><br><span class="line"><span class="comment">             * 比如回调DisposableBean接口的destroy()方法，需要注意的是这里只是注册，并不会执行销毁回调方法。</span></span><br><span class="line"><span class="comment">             * 销毁方法的调用是在手动执行容器的关闭方法的时候：</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> org.springframework.context.support.AbstractApplicationContext#close()</span></span><br><span class="line"><span class="comment">             *</span></span><br><span class="line"><span class="comment">             * <span class="doctag">@see</span> AbstractBeanFactory#registerDisposableBeanIfNecessary(String, Object, RootBeanDefinition)</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    registerDisposableBeanIfNecessary(beanName, bean, mbd);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (BeanDefinitionValidationException ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">      mbd.getResourceDescription(), beanName, <span class="string">&quot;Invalid destruction signature&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 回到调用处：</span></span><br><span class="line"><span class="comment">         * <span class="doctag">@see</span> #createBean(String, RootBeanDefinition, Object[])</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  <span class="keyword">return</span> exposedObject;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个方法非常复杂，完成对象创建，属性填充，依赖注入，初始化。</p>
<ol>
<li>createBeanInstance(beanName, mbd, args)方法完成对象创建</li>
<li>applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)方法完成@Resource、@Autowired、@Value注解的定义信息加载。</li>
<li>addSingletonFactory(beanName, () -&gt; getEarlyBeanReference(beanName, mbd, bean))方法尝试获取一个早期的引用</li>
<li>populateBean(beanName, mbd, instanceWrapper)方法执行后置处理器的<code>postProcessAfterInstantiation()</code>方法，完成<code>@Autowired，@Resource，@Value</code>注解的属性值注入。</li>
<li>initializeBean(beanName, exposedObject, mbd)方法执行各种初始化回调方法</li>
<li>registerDisposableBeanIfNecessary(beanName, bean, mbd)方法完成bean的各种销毁方法的注册</li>
</ol>
<h6 id="1-createBeanInstance-beanName-mbd-args"><a href="#1-createBeanInstance-beanName-mbd-args" class="headerlink" title="1. createBeanInstance(beanName, mbd, args)"></a>1. createBeanInstance(beanName, mbd, args)</h6><p>这个方法最底层是通过反射的<code>newInstance()</code>方法创建对象。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> BeanWrapper <span class="title">createBeanInstance</span><span class="params">(String beanName, RootBeanDefinition mbd, <span class="meta">@Nullable</span> Object[] args)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// Make sure bean class is actually resolved at this point.</span></span><br><span class="line">  Class&lt;?&gt; beanClass = resolveBeanClass(mbd, beanName);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 检查bean的访问类型，比如是public并且是非final</span></span><br><span class="line">  <span class="keyword">if</span> (beanClass != <span class="keyword">null</span> &amp;&amp; !Modifier.isPublic(beanClass.getModifiers()) &amp;&amp; !mbd.isNonPublicAccessAllowed()) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                                    <span class="string">&quot;Bean class isn&#x27;t public, and non-public access not allowed: &quot;</span> + beanClass.getName());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 存在Supplier回调则使用回调里的方法创建实例（jdk1.8）之后的才有的特性</span></span><br><span class="line">  <span class="comment">// 通过instanceSupplier.get()方法返回实例</span></span><br><span class="line">  Supplier&lt;?&gt; instanceSupplier = mbd.getInstanceSupplier();</span><br><span class="line">  <span class="keyword">if</span> (instanceSupplier != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> obtainFromSupplier(instanceSupplier, beanName);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 通过工厂方法创建实例</span></span><br><span class="line">  <span class="keyword">if</span> (mbd.getFactoryMethodName() != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> instantiateUsingFactoryMethod(beanName, mbd, args);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Shortcut when re-creating the same bean...</span></span><br><span class="line">  <span class="comment">// 通过constructorArgumentsResolved标记起到了缓存的作用</span></span><br><span class="line">  <span class="comment">// 当容器创建同一个类型bean的时候（非单例情况），可以直接使用构造器创建，不需要再此解析构造器上的参数。</span></span><br><span class="line">  <span class="comment">// 参数的解析的开销也是不小的。</span></span><br><span class="line">  <span class="keyword">boolean</span> resolved = <span class="keyword">false</span>;</span><br><span class="line">  <span class="keyword">boolean</span> autowireNecessary = <span class="keyword">false</span>;</span><br><span class="line">  <span class="keyword">if</span> (args == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">synchronized</span> (mbd.constructorArgumentLock) &#123;</span><br><span class="line">      <span class="keyword">if</span> (mbd.resolvedConstructorOrFactoryMethod != <span class="keyword">null</span>) &#123;</span><br><span class="line">        resolved = <span class="keyword">true</span>;</span><br><span class="line">        <span class="comment">// constructorArgumentsResolved标记了构造器的参数都已经解析完成</span></span><br><span class="line">        autowireNecessary = mbd.constructorArgumentsResolved;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (resolved) &#123;</span><br><span class="line">    <span class="keyword">if</span> (autowireNecessary) &#123;</span><br><span class="line">      <span class="comment">/**</span></span><br><span class="line"><span class="comment">                 * 通过有参构造方法创建，并自动注入构造方法中的参数值，如果有对象依赖在方法内部又会调getBean()方法创建bean实例</span></span><br><span class="line"><span class="comment">                 * 然后注入到对应的属性上。比如这个bean，构造方法引用了另外一个RefrenceBeanA</span></span><br><span class="line"><span class="comment">                 * <span class="doctag">@see</span> com.ubuntuvim.spring.createbean.HasArgsConstructBean</span></span><br><span class="line"><span class="comment">                 * &lt;pre&gt;</span></span><br><span class="line"><span class="comment">                 * <span class="doctag">@Component</span></span></span><br><span class="line"><span class="comment">                 * public class HasArgsConstructBean &#123;</span></span><br><span class="line"><span class="comment">                 *       private RefrenceBeanA refrenceBeanA;</span></span><br><span class="line"><span class="comment">                 *</span></span><br><span class="line"><span class="comment">                 *       public HasArgsConstructBean(RefrenceBeanA refrenceBeanA) &#123;</span></span><br><span class="line"><span class="comment">                 *           this.refrenceBeanA = refrenceBeanA;</span></span><br><span class="line"><span class="comment">                 *    &#125;</span></span><br><span class="line"><span class="comment">                 * &#125;</span></span><br><span class="line"><span class="comment">                 * &lt;/pre&gt;</span></span><br><span class="line"><span class="comment">                  */</span></span><br><span class="line">      <span class="keyword">return</span> autowireConstructor(beanName, mbd, <span class="keyword">null</span>, <span class="keyword">null</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// 使用默认的无参构造方法创建实例，底层使用反射newInstance()方法创建对象</span></span><br><span class="line">      <span class="keyword">return</span> instantiateBean(beanName, mbd);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Candidate constructors for autowiring?</span></span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 如果有依赖注入的构造器</span></span><br><span class="line"><span class="comment">         * 方法内部会调用后置处理器获取定制化的构造器列表，如果没有任何后置处理器的实现则返回null</span></span><br><span class="line"><span class="comment">         * <span class="doctag">@see</span> SmartInstantiationAwareBeanPostProcessor</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  Constructor&lt;?&gt;[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);</span><br><span class="line">  <span class="keyword">if</span> (ctors != <span class="keyword">null</span> || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||</span><br><span class="line">      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) &#123;</span><br><span class="line">    <span class="keyword">return</span> autowireConstructor(beanName, mbd, ctors, args);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Preferred constructors for default construction?</span></span><br><span class="line">  <span class="comment">// 如果有默认的构造器</span></span><br><span class="line">  ctors = mbd.getPreferredConstructors();</span><br><span class="line">  <span class="keyword">if</span> (ctors != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> autowireConstructor(beanName, mbd, ctors, <span class="keyword">null</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// No special handling: simply use no-arg constructor.</span></span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 前面的构造器都没有则最后使用无参构造器创建实例</span></span><br><span class="line"><span class="comment">         * 底层使用反射newInstance()方法创建对象</span></span><br><span class="line"><span class="comment">         * 实例创建完成，回到调用处：</span></span><br><span class="line"><span class="comment">         * <span class="doctag">@see</span> AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[])</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  <span class="keyword">return</span> instantiateBean(beanName, mbd);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>instantiateBean()</code>方法的代码我就不贴了，底层使用反射newInstance()方法创建对象。</p>
<h6 id="applyMergedBeanDefinitionPostProcessors-mbd-beanType-beanName"><a href="#applyMergedBeanDefinitionPostProcessors-mbd-beanType-beanName" class="headerlink" title="applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)"></a>applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">applyMergedBeanDefinitionPostProcessors</span><span class="params">(RootBeanDefinition mbd, Class&lt;?&gt; beanType, String beanName)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (BeanPostProcessor bp : getBeanPostProcessors()) &#123;</span><br><span class="line">    <span class="keyword">if</span> (bp <span class="keyword">instanceof</span> MergedBeanDefinitionPostProcessor) &#123;</span><br><span class="line">      MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;</span><br><span class="line">      bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个方法比较简单，就是执行容器中后置处理器<code>MergedBeanDefinitionPostProcessor</code>的<code>postProcessMergedBeanDefinition()</code>方法。</p>
<p>这个后置处理器有两个非常重要的实现类。一个是<code>AutowiredAnnotationBeanPostProcessor</code>，一个是<code>CommonAnnotationBeanPostProcessor</code>，这两个后置处理器的实现在这里主要是用来扫描@Resource、@Autowired、@Value注解的定义信息</p>
<h6 id="addSingletonFactory-beanName-gt-getEarlyBeanReference-beanName-mbd-bean"><a href="#addSingletonFactory-beanName-gt-getEarlyBeanReference-beanName-mbd-bean" class="headerlink" title="addSingletonFactory(beanName, () -&gt; getEarlyBeanReference(beanName, mbd, bean))"></a>addSingletonFactory(beanName, () -&gt; getEarlyBeanReference(beanName, mbd, bean))</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">getEarlyBeanReference</span><span class="params">(String beanName, RootBeanDefinition mbd, Object bean)</span> </span>&#123;</span><br><span class="line">  Object exposedObject = bean;</span><br><span class="line">  <span class="keyword">if</span> (!mbd.isSynthetic() &amp;&amp; hasInstantiationAwareBeanPostProcessors()) &#123;</span><br><span class="line">    <span class="keyword">for</span> (BeanPostProcessor bp : getBeanPostProcessors()) &#123;</span><br><span class="line">      <span class="keyword">if</span> (bp <span class="keyword">instanceof</span> SmartInstantiationAwareBeanPostProcessor) &#123;</span><br><span class="line">        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;</span><br><span class="line">        <span class="comment">// 获取提前暴露的bean引用，主要用于解决循环依赖，只有单例bean调用此方法</span></span><br><span class="line">        exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> exposedObject;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h6 id="populateBean-beanName-mbd-instanceWrapper"><a href="#populateBean-beanName-mbd-instanceWrapper" class="headerlink" title="populateBean(beanName, mbd, instanceWrapper)"></a>populateBean(beanName, mbd, instanceWrapper)</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">populateBean</span><span class="params">(String beanName, RootBeanDefinition mbd, <span class="meta">@Nullable</span> BeanWrapper bw)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 前面创建的bean实例为空时</span></span><br><span class="line">  <span class="keyword">if</span> (bw == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (mbd.hasPropertyValues()) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">        mbd.getResourceDescription(), beanName, <span class="string">&quot;Cannot apply property values to null instance&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// Skip property population phase for null instance.</span></span><br><span class="line">      <span class="comment">// 当前bean实例都是null也就无法填充属性值了，直接返回</span></span><br><span class="line">      <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the</span></span><br><span class="line">  <span class="comment">// state of the bean before properties are set. This can be used, for example,</span></span><br><span class="line">  <span class="comment">// to support styles of field injection.</span></span><br><span class="line">  <span class="comment">// 执行后置处理器InstantiationAwareBeanPostProcessor，提供一个机会让开发者可以在bean实例化后，初始化前做一些操作。</span></span><br><span class="line">  <span class="keyword">if</span> (!mbd.isSynthetic() &amp;&amp; hasInstantiationAwareBeanPostProcessors()) &#123;</span><br><span class="line">    <span class="keyword">for</span> (BeanPostProcessor bp : getBeanPostProcessors()) &#123;</span><br><span class="line">      <span class="keyword">if</span> (bp <span class="keyword">instanceof</span> InstantiationAwareBeanPostProcessor) &#123;</span><br><span class="line">        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;</span><br><span class="line">        <span class="comment">// 如果返回false则直接退出当前方法，不进行下面的属性填充操作，所以一定要非常注意后置处理器的返回值以及执行顺序。</span></span><br><span class="line">        <span class="keyword">if</span> (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) &#123;</span><br><span class="line">          <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 获取属性值</span></span><br><span class="line">  PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : <span class="keyword">null</span>);</span><br><span class="line">  <span class="comment">// 获取注入模式（byType或者byName)</span></span><br><span class="line">  <span class="keyword">int</span> resolvedAutowireMode = mbd.getResolvedAutowireMode();</span><br><span class="line">  <span class="keyword">if</span> (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) &#123;</span><br><span class="line">    <span class="comment">// 把属性值再做一次包装，转换成一个MutablePropertyValues对象。</span></span><br><span class="line">    MutablePropertyValues newPvs = <span class="keyword">new</span> MutablePropertyValues(pvs);</span><br><span class="line">    <span class="comment">// Add property values based on autowire by name if applicable.</span></span><br><span class="line">    <span class="comment">// 如果适用，根据类型添加基于自动装配的属性值。</span></span><br><span class="line">    <span class="keyword">if</span> (resolvedAutowireMode == AUTOWIRE_BY_NAME) &#123;</span><br><span class="line">      autowireByName(beanName, mbd, bw, newPvs);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// Add property values based on autowire by type if applicable.</span></span><br><span class="line">    <span class="comment">// 如果适用，根据类型添加基于自动装配的属性值。</span></span><br><span class="line">    <span class="keyword">if</span> (resolvedAutowireMode == AUTOWIRE_BY_TYPE) &#123;</span><br><span class="line">      autowireByType(beanName, mbd, bw, newPvs);</span><br><span class="line">    &#125;</span><br><span class="line">    pvs = newPvs;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 存在InstantiationAwareBeanPostProcessor后置处理器</span></span><br><span class="line">  <span class="keyword">boolean</span> hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();</span><br><span class="line"></span><br><span class="line">  PropertyDescriptor[] filteredPds = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (hasInstAwareBpps) &#123;</span><br><span class="line">    <span class="comment">// 依赖注入模式不是byType或者byName的情况有可能为空，这两种情况执行了pvs = newPvs不会为null</span></span><br><span class="line">    <span class="keyword">if</span> (pvs == <span class="keyword">null</span>) &#123;</span><br><span class="line">      pvs = mbd.getPropertyValues();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (BeanPostProcessor bp : getBeanPostProcessors()) &#123;</span><br><span class="line">      <span class="keyword">if</span> (bp <span class="keyword">instanceof</span> InstantiationAwareBeanPostProcessor) &#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">                     * 属性注入，包括依赖对象注入，依赖集合注入，</span></span><br><span class="line"><span class="comment">                     * 比如下面这3种写法，都会在此完成属性注入</span></span><br><span class="line"><span class="comment">                     * &lt;pre&gt;</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@Autowired</span></span></span><br><span class="line"><span class="comment">                     * private Fruit apple;</span></span><br><span class="line"><span class="comment">                     *</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@Autowired</span></span></span><br><span class="line"><span class="comment">                     * private List&lt;InterfaceA&gt; interfaceAList;</span></span><br><span class="line"><span class="comment">                     *</span></span><br><span class="line"><span class="comment">                     * 同理，Map也是一样的</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@Autowired</span></span></span><br><span class="line"><span class="comment">                     * private Map&lt;String, InterfaceA&gt; interfaceAMap;</span></span><br><span class="line"><span class="comment">                     * key就是实现类的beanName，value就是实现类实例对象。</span></span><br><span class="line"><span class="comment">                     * &lt;/pre&gt;</span></span><br><span class="line"><span class="comment">                     * 其中AutowiredAnnotationBeanPostProcessor这个后置处理器用于给<span class="doctag">@Autowired</span>注解或者<span class="doctag">@Value</span>注解定义的属性注入值，</span></span><br><span class="line"><span class="comment">                     * 注入的步骤：1. 扫描bean实例中使用<span class="doctag">@Autowired</span>注解的属性和方法，2. 根据注入的类型从IoC容器中在匹配的bean；3. 通过反射执行赋值操作</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues</span></span><br><span class="line"><span class="comment">                     *</span></span><br><span class="line"><span class="comment">                     * 其中CommonAnnotationBeanPostProcessor这个后置处理器用于给<span class="doctag">@Resource</span>注解定义的属性注入值</span></span><br><span class="line"><span class="comment">                     * 同时这个类还处理了<span class="doctag">@PostConstruct</span>/<span class="doctag">@PreDestroy</span>这两个注解</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties</span></span><br><span class="line"><span class="comment">                     */</span></span><br><span class="line">        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;</span><br><span class="line">        <span class="comment">// postProcessProperties()方法已经声明为过时。推荐使用postProcessPropertyValues()方法</span></span><br><span class="line">        PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);</span><br><span class="line">        <span class="keyword">if</span> (pvsToUse == <span class="keyword">null</span>) &#123;</span><br><span class="line">          <span class="keyword">if</span> (filteredPds == <span class="keyword">null</span>) &#123;</span><br><span class="line">            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);</span><br><span class="line">          &#125;</span><br><span class="line">          pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);</span><br><span class="line">          <span class="comment">// 如果返回的属性值为null直接退出当前方法，说明没有可填充的属性</span></span><br><span class="line">          <span class="comment">// 在实现后置处理器的时候特别要注意接口方法的返回值已经执行顺序，如果第一个后置处理器就返回了null，</span></span><br><span class="line">          <span class="comment">// 那么同一类型的其他排在后面的就不会执行了</span></span><br><span class="line">          <span class="keyword">if</span> (pvsToUse == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        pvs = pvsToUse;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 是否需要依赖检查，DEPENDENCY_CHECK_NONE标识不需要依赖检查</span></span><br><span class="line">  <span class="keyword">boolean</span> needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);</span><br><span class="line">  <span class="keyword">if</span> (needsDepCheck) &#123;</span><br><span class="line">    <span class="keyword">if</span> (filteredPds == <span class="keyword">null</span>) &#123;</span><br><span class="line">      filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);</span><br><span class="line">    &#125;</span><br><span class="line">    checkDependencies(beanName, mbd, filteredPds, pvs);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (pvs != <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">             * 处理xml方式的&lt;property&gt;标签。比如下面的bean</span></span><br><span class="line"><span class="comment">             * &lt;bean id=&quot;testBean&quot; class=&quot;com.ubuntuvim.spring.TestBean&quot;&gt;</span></span><br><span class="line"><span class="comment">             *         &lt;property name=&quot;name&quot; value=&quot;ubuntuvim&quot; /&gt;</span></span><br><span class="line"><span class="comment">             *         &lt;property name=&quot;address&quot; value=&quot;china&quot; /&gt;</span></span><br><span class="line"><span class="comment">             * &lt;/bean&gt;</span></span><br><span class="line"><span class="comment">             */</span></span><br><span class="line">    applyPropertyValues(beanName, mbd, bw, pvs);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个方法实现也是非常复杂的，它所完成的事情在代码的注释上已经有说明。</p>
<h6 id="initializeBean-beanName-exposedObject-mbd"><a href="#initializeBean-beanName-exposedObject-mbd" class="headerlink" title="initializeBean(beanName, exposedObject, mbd)"></a>initializeBean(beanName, exposedObject, mbd)</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">initializeBean</span><span class="params">(<span class="keyword">final</span> String beanName, <span class="keyword">final</span> Object bean, <span class="meta">@Nullable</span> RootBeanDefinition mbd)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 如果bean实现了XxxAware接口，则调用这些接口的setXxx()方法</span></span><br><span class="line">  <span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">    AccessController.doPrivileged((PrivilegedAction&lt;Object&gt;) () -&gt; &#123;</span><br><span class="line">      invokeAwareMethods(beanName, bean);</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;, getAccessControlContext());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    invokeAwareMethods(beanName, bean);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 执行后置处理器的postProcessorBeforeInitialization()方法</span></span><br><span class="line"><span class="comment">         * 这里会首先执行第一个初始化回调<span class="doctag">@PostConstruct</span>声明的方法，是这个类实现的</span></span><br><span class="line"><span class="comment">         * <span class="doctag">@see</span> org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  Object wrappedBean = bean;</span><br><span class="line">  <span class="keyword">if</span> (mbd == <span class="keyword">null</span> || !mbd.isSynthetic()) &#123;</span><br><span class="line">    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// 执行InitializingBean接口和自定义的初始化方法（@Bean(initMethod = &quot;beanInit&quot;))</span></span><br><span class="line">    invokeInitMethods(beanName, wrappedBean, mbd);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">      (mbd != <span class="keyword">null</span> ? mbd.getResourceDescription() : <span class="keyword">null</span>),</span><br><span class="line">      beanName, <span class="string">&quot;Invocation of init method failed&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 执行后置处理器的postProcessorAfterInitialization()方法</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  <span class="keyword">if</span> (mbd == <span class="keyword">null</span> || !mbd.isSynthetic()) &#123;</span><br><span class="line">    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 完成各种初始化回调方法，回到调用处：</span></span><br><span class="line"><span class="comment">         * <span class="doctag">@see</span> #doCreateBean(String, RootBeanDefinition, Object[]) </span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">  <span class="keyword">return</span> wrappedBean;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个方法主要完成属性的填充，依赖注入。详细过程代码注释已经有描述。</p>
<h6 id="registerDisposableBeanIfNecessary-beanName-bean-mbd"><a href="#registerDisposableBeanIfNecessary-beanName-bean-mbd" class="headerlink" title="registerDisposableBeanIfNecessary(beanName, bean, mbd)"></a>registerDisposableBeanIfNecessary(beanName, bean, mbd)</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">registerDisposableBeanIfNecessary</span><span class="params">(String beanName, Object bean, RootBeanDefinition mbd)</span> </span>&#123;</span><br><span class="line">  AccessControlContext acc = (System.getSecurityManager() != <span class="keyword">null</span> ? getAccessControlContext() : <span class="keyword">null</span>);</span><br><span class="line">  <span class="comment">// 非原型bean &amp;&amp; （bean实例内使用里@PreDestory注解 || bean实现了DisposableBean接口</span></span><br><span class="line">  <span class="comment">//                 || 容器中注册了DestructionAwareBeanPostProcessor后置处理器）</span></span><br><span class="line">  <span class="keyword">if</span> (!mbd.isPrototype() &amp;&amp; requiresDestruction(bean, mbd)) &#123;</span><br><span class="line">    <span class="comment">// 单例bean</span></span><br><span class="line">    <span class="keyword">if</span> (mbd.isSingleton()) &#123;</span><br><span class="line">      <span class="comment">// Register a DisposableBean implementation that performs all destruction</span></span><br><span class="line">      <span class="comment">// work for the given bean: DestructionAwareBeanPostProcessors,</span></span><br><span class="line">      <span class="comment">// DisposableBean interface, custom destroy method.</span></span><br><span class="line">      <span class="comment">/**</span></span><br><span class="line"><span class="comment">                 * 把销毁回调方法包装成DisposableBeanAdapter并注册到容器中，待手动调用容器的close()方法的时候执行</span></span><br><span class="line"><span class="comment">                 * 包括：</span></span><br><span class="line"><span class="comment">                 * 1. <span class="doctag">@Bean</span>注解中自定义的销毁回调方法</span></span><br><span class="line"><span class="comment">                 * 2. <span class="doctag">@PreDestory</span>注解的回调方法</span></span><br><span class="line"><span class="comment">                 * 3. 实现DispoableBean接口的detory()回调方法</span></span><br><span class="line"><span class="comment">                 * 4. 后置处理器DestructionAwareBeanPostProcessor的postProcessBeforeDestruction()方法</span></span><br><span class="line"><span class="comment">                 */</span></span><br><span class="line">      registerDisposableBean(beanName,</span><br><span class="line">                             <span class="keyword">new</span> DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 非单例、非原型bean</span></span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// A bean with a custom scope...</span></span><br><span class="line">      Scope scope = <span class="keyword">this</span>.scopes.get(mbd.getScope());</span><br><span class="line">      <span class="keyword">if</span> (scope == <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">&quot;No Scope registered for scope name &#x27;&quot;</span> + mbd.getScope() + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      scope.registerDestructionCallback(beanName,</span><br><span class="line">                                        <span class="keyword">new</span> DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>到处完成普通对象的创建、初始化、执行初始回调等操作。</p>
<h5 id="AbstractBeanFactory-getObjectForBeanInstance"><a href="#AbstractBeanFactory-getObjectForBeanInstance" class="headerlink" title="AbstractBeanFactory.getObjectForBeanInstance()"></a>AbstractBeanFactory.getObjectForBeanInstance()</h5><p>第二个方法是当前类实现的：<code>AbstractBeanFactory.getObjectForBeanInstance()</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">getObjectForBeanInstance</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">  Object beanInstance, String name, String beanName, <span class="meta">@Nullable</span> RootBeanDefinition mbd)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Don&#x27;t let calling code try to dereference the factory if the bean isn&#x27;t a factory.</span></span><br><span class="line">  <span class="comment">// 如果不是FactoryBean，为了以防开发者自定义的bean名字也加了&amp;前缀，因为Spring默认&amp;开头的bean是工厂bean</span></span><br><span class="line">  <span class="keyword">if</span> (BeanFactoryUtils.isFactoryDereference(name)) &#123;</span><br><span class="line">    <span class="keyword">if</span> (beanInstance <span class="keyword">instanceof</span> NullBean) &#123;</span><br><span class="line">      <span class="keyword">return</span> beanInstance;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (!(beanInstance <span class="keyword">instanceof</span> FactoryBean)) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanIsNotAFactoryException(beanName, beanInstance.getClass());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (mbd != <span class="keyword">null</span>) &#123;</span><br><span class="line">      mbd.isFactoryBean = <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> beanInstance;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Now we have the bean instance, which may be a normal bean or a FactoryBean.</span></span><br><span class="line">  <span class="comment">// If it&#x27;s a FactoryBean, we use it to create a bean instance, unless the</span></span><br><span class="line">  <span class="comment">// caller actually wants a reference to the factory.</span></span><br><span class="line">  <span class="comment">// 如果不是FactoryBean则无需通过调用getObject方法获取实例，</span></span><br><span class="line">  <span class="comment">// 正常情况下普通的bean已经在前面的doCreateBean方法中创建好了</span></span><br><span class="line">  <span class="keyword">if</span> (!(beanInstance <span class="keyword">instanceof</span> FactoryBean)) &#123;</span><br><span class="line">    <span class="keyword">return</span> beanInstance;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  Object object = <span class="keyword">null</span>;</span><br><span class="line">  <span class="keyword">if</span> (mbd != <span class="keyword">null</span>) &#123;</span><br><span class="line">    mbd.isFactoryBean = <span class="keyword">true</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 从FactoryBean对象缓存中获取</span></span><br><span class="line">    object = getCachedObjectForFactoryBean(beanName);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (object == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="comment">// Return bean instance from factory.</span></span><br><span class="line">    <span class="comment">// 获取工厂bean实例本身</span></span><br><span class="line">    FactoryBean&lt;?&gt; factory = (FactoryBean&lt;?&gt;) beanInstance;</span><br><span class="line">    <span class="comment">// Caches object obtained from FactoryBean if it is a singleton.</span></span><br><span class="line">    <span class="keyword">if</span> (mbd == <span class="keyword">null</span> &amp;&amp; containsBeanDefinition(beanName)) &#123;</span><br><span class="line">      mbd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">boolean</span> synthetic = (mbd != <span class="keyword">null</span> &amp;&amp; mbd.isSynthetic());</span><br><span class="line">    <span class="comment">// 调用工厂bean的getObject方法获取对象实例</span></span><br><span class="line">    object = getObjectFromFactoryBean(factory, beanName, !synthetic);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> object;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>前面一大推都是判断和校验，真正创建实例对象是在<code>getObjectFromFactoryBean()</code>方法中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">getObjectFromFactoryBean</span><span class="params">(FactoryBean&lt;?&gt; factory, String beanName, <span class="keyword">boolean</span> shouldPostProcess)</span> </span>&#123;</span><br><span class="line">  <span class="comment">// FactoryBean接口中的isSingleton()方法返回的值作用是：</span></span><br><span class="line">  <span class="comment">// 由FactoryBean创建出来的bean实例的作用域是singleton还是prototype，</span></span><br><span class="line">  <span class="comment">// 如果返回false，表示由这个FactoryBean创建的对象是多例的，</span></span><br><span class="line">  <span class="comment">// 那么我们每次从容器中getBean的时候都会去重新调用FactoryBean中的getObject方法获取一个新的对象。</span></span><br><span class="line">  <span class="comment">// 若返回true，表示创建的对象是单例的，那么我们每次从容器中获取这个对象的时候都是同一个对象（直接从单例缓存中获取）。</span></span><br><span class="line">  <span class="keyword">if</span> (factory.isSingleton() &amp;&amp; containsSingleton(beanName)) &#123;</span><br><span class="line">    <span class="keyword">synchronized</span> (getSingletonMutex()) &#123;</span><br><span class="line">      Object object = <span class="keyword">this</span>.factoryBeanObjectCache.get(beanName);</span><br><span class="line">      <span class="keyword">if</span> (object == <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="comment">// 调用工厂bean的getObject方法获取对象实例</span></span><br><span class="line">        object = doGetObjectFromFactoryBean(factory, beanName);</span><br><span class="line">        <span class="comment">// Only post-process and store if not put there already during getObject() call above</span></span><br><span class="line">        <span class="comment">// (e.g. because of circular reference processing triggered by custom getBean calls)</span></span><br><span class="line">        Object alreadyThere = <span class="keyword">this</span>.factoryBeanObjectCache.get(beanName);</span><br><span class="line">        <span class="keyword">if</span> (alreadyThere != <span class="keyword">null</span>) &#123;</span><br><span class="line">          object = alreadyThere;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="keyword">if</span> (shouldPostProcess) &#123;</span><br><span class="line">            <span class="keyword">if</span> (isSingletonCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">              <span class="comment">// Temporarily return non-post-processed object, not storing it yet..</span></span><br><span class="line">              <span class="keyword">return</span> object;</span><br><span class="line">            &#125;</span><br><span class="line">            beforeSingletonCreation(beanName);</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">              <span class="comment">/**</span></span><br><span class="line"><span class="comment">                                 * 调用子类的实现。用于执行后置处理器，对bean实例做增强。</span></span><br><span class="line"><span class="comment">                                 * <span class="doctag">@see</span> AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean</span></span><br><span class="line"><span class="comment">                                 */</span></span><br><span class="line">              object = postProcessObjectFromFactoryBean(object, beanName);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">              <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(beanName,</span><br><span class="line">                                              <span class="string">&quot;Post-processing of FactoryBean&#x27;s singleton object failed&quot;</span>, ex);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">finally</span> &#123;</span><br><span class="line">              afterSingletonCreation(beanName);</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">if</span> (containsSingleton(beanName)) &#123;</span><br><span class="line">            <span class="keyword">this</span>.factoryBeanObjectCache.put(beanName, object);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> object;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 如果FactoryBean接口中的isSingleton()方法返回的是true，</span></span><br><span class="line">  <span class="comment">// 表示通过工厂bean创建出来的bean对象不是单例的，所以不需要缓存每次都是创建一个新的对象实例</span></span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 调用工厂bean的getObject方法获取对象实例</span></span><br><span class="line">    Object object = doGetObjectFromFactoryBean(factory, beanName);</span><br><span class="line">    <span class="keyword">if</span> (shouldPostProcess) &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">                     * 调用子类的实现。用于执行后置处理器，对bean实例做增强。</span></span><br><span class="line"><span class="comment">                     * <span class="doctag">@see</span> AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean</span></span><br><span class="line"><span class="comment">                     */</span></span><br><span class="line">        object = postProcessObjectFromFactoryBean(object, beanName);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(beanName, <span class="string">&quot;Post-processing of FactoryBean&#x27;s object failed&quot;</span>, ex);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> object;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>然后创建的逻辑还没到！！具体处理逻辑通常都是放在<code>do</code>开头的方法中。从上面的代码可以看出来<code>FactoryBean</code>接口的提供的方法其实针对的是接口创建出来的bean对象，而不是对工厂实例本身的设置。</p>
<p>比如接口中的<code>isSingleton()</code>方法，设置的是工厂创建出来的bean是单例（返回值是<code>true</code>）的还是非单例的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> Object <span class="title">doGetObjectFromFactoryBean</span><span class="params">(<span class="keyword">final</span> FactoryBean&lt;?&gt; factory, <span class="keyword">final</span> String beanName)</span></span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> BeanCreationException </span>&#123;</span><br><span class="line"></span><br><span class="line">  Object object;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// 调用工厂bean的getObject方法获取对象实例</span></span><br><span class="line">    <span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">      AccessControlContext acc = getAccessControlContext();</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        object = AccessController.doPrivileged((PrivilegedExceptionAction&lt;Object&gt;) factory::getObject, acc);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (PrivilegedActionException pae) &#123;</span><br><span class="line">        <span class="keyword">throw</span> pae.getException();</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      object = factory.getObject();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (FactoryBeanNotInitializedException ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName, ex.toString());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(beanName, <span class="string">&quot;FactoryBean threw exception on object creation&quot;</span>, ex);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Do not accept a null value for a FactoryBean that&#x27;s not fully</span></span><br><span class="line">  <span class="comment">// initialized yet: Many FactoryBeans just return null then.</span></span><br><span class="line">  <span class="comment">// 不接受null对象，如果开发者实现了FactoryBean接口，但是在getObject方法中返回了null，那么Spring会默认返回的一个NullBean对象实例</span></span><br><span class="line">  <span class="keyword">if</span> (object == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (isSingletonCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(</span><br><span class="line">        beanName, <span class="string">&quot;FactoryBean which is currently in creation returned null from getObject&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    object = <span class="keyword">new</span> NullBean();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> object;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个方法的逻辑就非常简单了，最核心就一句代码<code>factory.getObject()</code>调用工厂bean的<code>getObject()</code>方法获取对象实例。</p>
<p>整个获取对象实例的过程和前面的<code>getSingleton</code>方法类似的，只是最后调用的工厂方法不一样，一个是调用<code>ObjectFactory.getObject()</code>方法创建普通实例对象，一个是调用<code>FactoryBean.getObject()</code>方法创建复杂实例对象。</p>
<p>对象创建完毕之后都会调用一大推的后置处理器。这些后置处理器会在bean的初始化前后做一些处理。</p>
<p><strong>到此完成所有单例对象的创建并做初始化、属性的填充。</strong>也就是<code>AbstractApplicationContext.finishBeanFactoryInitialization()</code>方法才执行完。</p>
<h3 id="finishRefresh"><a href="#finishRefresh" class="headerlink" title="finishRefresh()"></a>finishRefresh()</h3><p>这个方法的实现比较简单，主要做的事情可以通过看源码就知道了。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">finishRefresh</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// Clear context-level resource caches (such as ASM metadata from scanning).</span></span><br><span class="line">  clearResourceCaches();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Initialize lifecycle processor for this context.</span></span><br><span class="line">  <span class="comment">// 初始化容器生命周期处理器</span></span><br><span class="line">  initLifecycleProcessor();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Propagate refresh to lifecycle processor first.</span></span><br><span class="line">  <span class="comment">// 执行实现fecycleProcessor接口的onRefresh()方法</span></span><br><span class="line">  getLifecycleProcessor().onRefresh();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Publish the final event.</span></span><br><span class="line">  <span class="comment">// 通过initApplicationEventMulticaster()方法注册事件发布器，给registerListeners()方法注册的监听器发布事件，</span></span><br><span class="line">    <span class="comment">// 事件的发布说白就是遍历所有的监听器，调用ApplicationListener接口的onApplicationEvent方法</span></span><br><span class="line">  publishEvent(<span class="keyword">new</span> ContextRefreshedEvent(<span class="keyword">this</span>));</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Participate in LiveBeansView MBean, if active.</span></span><br><span class="line">  LiveBeansView.registerApplicationContext(<span class="keyword">this</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>到此，终于是把Spring容器的整个过程整了一遍。</p>
<h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p>IoC原理整篇：</p>
<p><a target="_blank" rel="noopener" href="https://www.cnblogs.com/ittangtang/p/3978349.html">https://www.cnblogs.com/ittangtang/p/3978349.html</a></p>
<p><strong>Bean定义</strong></p>
<p><a target="_blank" rel="noopener" href="https://cloud.tencent.com/developer/article/1497805">https://cloud.tencent.com/developer/article/1497805</a></p>
<p><strong>Bean实例化</strong></p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/jy02268879/article/details/87940150">https://blog.csdn.net/jy02268879/article/details/87940150</a></p>
<p><strong>bean生命周期简介</strong></p>
<ol>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/alex_xfboy/article/details/51211054">https://blog.csdn.net/alex_xfboy/article/details/51211054</a></li>
</ol>
<p><strong>bean初始化回调接口</strong></p>
<ol>
<li>SmartInitializingSingleton：<a target="_blank" rel="noopener" href="https://blog.csdn.net/alex_xfboy/article/details/88808025">https://blog.csdn.net/alex_xfboy/article/details/88808025</a></li>
</ol>
<p><strong>后置处理器</strong></p>
<p>所有后置处理器执行顺序图：</p>
<p><a target="_blank" rel="noopener" href="https://tech.souyunku.com/wp-content/uploads/2020/8/822/202244/2/86_1.png">https://tech.souyunku.com/wp-content/uploads/2020/8/822/202244/2/86_1.png</a></p>
<ol>
<li><p>InstantiationAwareBeanPostProcessor</p>
<p> <a target="_blank" rel="noopener" href="https://cloud.tencent.com/developer/article/1409273">https://cloud.tencent.com/developer/article/1409273</a></p>
<p> <a target="_blank" rel="noopener" href="https://my.oschina.net/u/3687664/blog/4267466">https://my.oschina.net/u/3687664/blog/4267466</a></p>
</li>
<li><p>MergeBeanDefinitionPostProcessor</p>
<p> <a target="_blank" rel="noopener" href="https://blog.csdn.net/luoyang_java/article/details/85709475">https://blog.csdn.net/luoyang_java/article/details/85709475</a></p>
</li>
<li><p>SmartInstantiationAwareBeanPostProcessor</p>
<p> <a target="_blank" rel="noopener" href="https://www.cnblogs.com/zhangjianbin/p/10059191.html">https://www.cnblogs.com/zhangjianbin/p/10059191.html</a></p>
</li>
</ol>
<p><strong>事件发布、订阅相关</strong></p>
<p><a target="_blank" rel="noopener" href="https://cxis.me/2017/02/15/Spring%E7%9A%84ApplicationContext%E4%BA%8B%E4%BB%B6%E6%9C%BA%E5%88%B6/">https://cxis.me/2017/02/15/Spring的ApplicationContext事件机制/</a></p>
<p><a target="_blank" rel="noopener" href="https://juejin.im/post/6854573214061264904">https://juejin.im/post/6854573214061264904</a></p>
<p><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/ef2cee8c5dd1">https://www.jianshu.com/p/ef2cee8c5dd1</a></p>

    </div>

      
    <div class="post-nav">
      <div class="post-nav-item post-nav-next">
        
          <span>〈 </span>
          <a href="/2020/09/23/Spring/Spring%E5%90%8E%E7%BD%AE%E5%A4%84%E7%90%86%E5%99%A8/" rel="next" title="Spring后置处理器">
          Spring后置处理器
          </a>
        
      </div>
  
      <div class="post-nav-item post-nav-prev">
          
      </div>
    </div>
  
  </article>
  <div class="toc-container">
    
  <div id="toc" class="toc-article">
    <strong class="toc-title">目录</strong>
    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#BeanDefinition%E5%AF%B9%E8%B1%A1"><span class="toc-text">BeanDefinition对象</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Spring%E4%B8%ADBean%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="toc-text">Spring中Bean生命周期</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Spring-IoC%E4%BD%93%E7%B3%BB%E7%BB%93%E6%9E%84"><span class="toc-text">Spring IoC体系结构</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#BeanFactory"><span class="toc-text">BeanFactory</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#BeanDefinition%EF%BC%88bean%E5%AE%9A%E4%B9%89%E4%BF%A1%E6%81%AF%EF%BC%8CIoC%E6%A0%B8%E5%BF%83%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%89"><span class="toc-text">BeanDefinition（bean定义信息，IoC核心数据结构）</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#IoC-%E5%AE%B9%E5%99%A8%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%81bean%E5%AE%9E%E4%BE%8B%E5%8C%96%EF%BC%88%E6%A0%B8%E5%BF%83%E5%86%85%E5%AE%B9%EF%BC%89"><span class="toc-text">IoC 容器初始化、bean实例化（核心内容）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#bean%E5%AE%9A%E4%B9%89%E8%B5%84%E6%BA%90%E5%87%86%E5%A4%87%EF%BC%88%E8%AE%BE%E7%BD%AExml%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84%E3%80%81%E8%AE%BE%E7%BD%AE%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD%E5%99%A8%EF%BC%89"><span class="toc-text">bean定义资源准备（设置xml配置文件路径、设置资源加载器）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8A%A0%E8%BD%BD%E3%80%81%E8%A7%A3%E6%9E%90%E3%80%81%E8%BD%AC%E6%8D%A2XML%E5%AE%9A%E4%B9%89%EF%BC%8C%E5%AE%9E%E4%BE%8B%E5%8C%96bean"><span class="toc-text">加载、解析、转换XML定义，实例化bean</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#prepareRefresh"><span class="toc-text">prepareRefresh()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#obtainFreshBeanFactory"><span class="toc-text">obtainFreshBeanFactory();</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E5%AE%B9%E5%99%A8%E3%80%81%E5%8A%A0%E8%BD%BDbean%E5%AE%9A%E4%B9%89%E4%BF%A1%E6%81%AF"><span class="toc-text">创建容器、加载bean定义信息</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%8A%A0%E8%BD%BDbean%E5%AE%9A%E4%B9%89"><span class="toc-text">加载bean定义</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#1-AbstractXmlApplicationContext-loadBeanDefinitions-beanDefinitionReader"><span class="toc-text">1. AbstractXmlApplicationContext.loadBeanDefinitions(beanDefinitionReader)</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#2-AbstractBeanDefinitionReader-loadBeanDefinitions-%E6%96%B9%E6%B3%95"><span class="toc-text">2. AbstractBeanDefinitionReader.loadBeanDefinitions()方法</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#3-DefaultResourceLoader-resourceLoader-getResource-location"><span class="toc-text">3. DefaultResourceLoader.resourceLoader.getResource(location)</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#4-AbstractBeanDefinitionReader-doLoadBeanDefinitions-inputSource-encodedResource-getResource"><span class="toc-text">4. AbstractBeanDefinitionReader.doLoadBeanDefinitions(inputSource, encodedResource.getResource())</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#5-%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAdocument%E8%A7%A3%E6%9E%90%E5%B7%A5%E5%8E%82"><span class="toc-text">5. 创建一个document解析工厂</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#6-%E8%B0%83%E7%94%A8registerBeanDefinitions-%E6%96%B9%E6%B3%95%E5%90%AF%E5%8A%A8bean%E5%AE%9A%E4%B9%89%E8%A7%A3%E6%9E%90"><span class="toc-text">6. 调用registerBeanDefinitions()方法启动bean定义解析</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#7-%E6%A0%87%E7%AD%BE%E8%BD%AC%E6%8D%A2%E6%88%90BeanDefinition"><span class="toc-text">7.  标签转换成BeanDefinition</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BF%9D%E5%AD%98%E8%BD%AC%E6%8D%A2%E5%90%8E%E7%9A%84BeanDefinition%E5%88%B0%E5%AE%B9%E5%99%A8%E7%BC%93%E5%AD%98%E4%B8%AD"><span class="toc-text">保存转换后的BeanDefinition到容器缓存中</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#prepareBeanFactory-beanFactory"><span class="toc-text">prepareBeanFactory(beanFactory)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#postProcessBeanFactory-beanFactory"><span class="toc-text">postProcessBeanFactory(beanFactory)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#invokeBeanFactoryPostProcessors-beanFactory"><span class="toc-text">invokeBeanFactoryPostProcessors(beanFactory)</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#postProcessBeanDefinitionRegistry-%E6%96%B9%E6%B3%95"><span class="toc-text">postProcessBeanDefinitionRegistry()方法</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#processConfigBeanDefinitions-%E6%96%B9%E6%B3%95"><span class="toc-text">processConfigBeanDefinitions()方法</span></a><ol class="toc-child"><li class="toc-item toc-level-6"><a class="toc-link" href="#parser-parse-candidates-%E8%A7%A3%E6%9E%90%E5%80%99%E9%80%89%E9%85%8D%E7%BD%AE%E7%B1%BB"><span class="toc-text">parser.parse(candidates)解析候选配置类</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#doProcessConfigurationClass%E8%A7%A3%E6%9E%90%E9%85%8D%E7%BD%AE%E7%B1%BB%E5%85%B7%E4%BD%93%E6%96%B9%E6%B3%95"><span class="toc-text">doProcessConfigurationClass解析配置类具体方法</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#this-reader-loadBeanDefinitions-configClasses-%E6%B3%A8%E5%86%8Cbean%E5%AE%9A%E4%B9%89"><span class="toc-text">this.reader.loadBeanDefinitions(configClasses)注册bean定义</span></a></li></ol></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#invokeBeanDefinitionRegistryPostProcessors-currentRegistryProcessors-registry-%E6%96%B9%E6%B3%95%E6%89%A7%E8%A1%8C%E6%B5%81%E7%A8%8B%E5%9B%BE"><span class="toc-text">invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法执行流程图</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#bean%E5%AE%9A%E4%B9%89%E5%90%8E%E7%BD%AE%E5%A4%84%E7%90%86%E5%99%A8%E4%BD%BF%E7%94%A8"><span class="toc-text">bean定义后置处理器使用</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#registerBeanPostProcessors-beanFactory"><span class="toc-text">registerBeanPostProcessors(beanFactory)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#initMessageSource"><span class="toc-text">initMessageSource()</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Spring%E6%96%B9%E6%B3%95%E6%BA%90%E7%A0%81"><span class="toc-text">Spring方法源码</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E4%BE%8B%E5%AD%90"><span class="toc-text">使用例子</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#initApplicationEventMulticaster"><span class="toc-text">initApplicationEventMulticaster()</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Spring%E4%B8%AD%E7%9A%84%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F"><span class="toc-text">Spring中的观察者模式</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%BA%90%E7%A0%81"><span class="toc-text">源码</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%A1%88%E4%BE%8B"><span class="toc-text">使用案例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#onRefresh"><span class="toc-text">onRefresh()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#registerListeners"><span class="toc-text">registerListeners()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#finishBeanFactoryInitialization-beanFactory"><span class="toc-text">finishBeanFactoryInitialization(beanFactory)</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#preInstantiateSingletons"><span class="toc-text">preInstantiateSingletons()</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#getBean-beanName"><span class="toc-text">getBean(beanName)</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#getSingleton-String-beanName-ObjectFactory-lt-gt-singletonFactory"><span class="toc-text">getSingleton(String beanName, ObjectFactory&lt;?&gt; singletonFactory)</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#AbstractAutowireCapableBeanFactory-createBean-beanName-mbd-args"><span class="toc-text">AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)</span></a><ol class="toc-child"><li class="toc-item toc-level-6"><a class="toc-link" href="#resolveBeforeInstantiation-beanName-mbdToUse"><span class="toc-text">resolveBeforeInstantiation(beanName, mbdToUse)</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#AbstractBeanFactory-doCreateBean-beanName-mbdToUse-args"><span class="toc-text">AbstractBeanFactory.doCreateBean(beanName, mbdToUse, args)</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#AbstractAutowireCapableBeanFactory-createBean"><span class="toc-text">AbstractAutowireCapableBeanFactory#createBean</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#doCreateBean-beanName-mbdToUse-args"><span class="toc-text">doCreateBean(beanName, mbdToUse, args);</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#1-createBeanInstance-beanName-mbd-args"><span class="toc-text">1. createBeanInstance(beanName, mbd, args)</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#applyMergedBeanDefinitionPostProcessors-mbd-beanType-beanName"><span class="toc-text">applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#addSingletonFactory-beanName-gt-getEarlyBeanReference-beanName-mbd-bean"><span class="toc-text">addSingletonFactory(beanName, () -&gt; getEarlyBeanReference(beanName, mbd, bean))</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#populateBean-beanName-mbd-instanceWrapper"><span class="toc-text">populateBean(beanName, mbd, instanceWrapper)</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#initializeBean-beanName-exposedObject-mbd"><span class="toc-text">initializeBean(beanName, exposedObject, mbd)</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#registerDisposableBeanIfNecessary-beanName-bean-mbd"><span class="toc-text">registerDisposableBeanIfNecessary(beanName, bean, mbd)</span></a></li></ol></li><li class="toc-item toc-level-5"><a class="toc-link" href="#AbstractBeanFactory-getObjectForBeanInstance"><span class="toc-text">AbstractBeanFactory.getObjectForBeanInstance()</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#finishRefresh"><span class="toc-text">finishRefresh()</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99"><span class="toc-text">参考资料</span></a></li></ol>
  </div>


  </div>
</div>


<div class="copyright">
    <span>本作品采用</span>
    <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by/4.0/">知识共享署名 4.0 国际许可协议</a>
    <span>进行许可。 转载时请注明原文链接。</span>
</div>
<div class="share">

</div>
<div class="post-container">
    <article class="post">
      <div id="container"></div>
    </article>
</div>

<link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css">
<script src="https://imsun.github.io/gitment/dist/gitment.browser.js"></script>
<script>
var gitment = new Gitment({
  id: 'Spring IoC原理', // 可选。默认为 location.href
  owner: 'ubuntuvim',
  repo: 'ubuntuvim.github.io',
  oauth: {
    client_id: '48b3df0bf4ba1743e0a3',
    client_secret: 'c6c2cec09acb5eecc9d325d56cef187264aa1e16',
  },
})
gitment.render('container')
</script>



    </div>

    

  </div>
  <footer class="footer text-center">
    <div id="bottom-inner">
        <a class="bottom-item" href="http://xcoding.tech/">首页</a> |
        <a class="bottom-item" href="http://xcoding.tech/" target="_blank">主站</a> |
        <a class="bottom-item" href="https://github.com/ubuntuvim" target="_blank">GitHub</a> |
        <a class="bottom-item" href="https://hexo.io" target="_blank">Powered by hexo</a> |
        <a class="bottom-item" href="https://github.com/KevinOfNeu/hexo-theme-xoxo" target="_blank">Theme xoxo</a>
    </div>
</footer>


  <script src='https://unpkg.com/mermaid@7.1.2/dist/mermaid.min.js'></script>
  <script>
    if (window.mermaid) {
      mermaid.initialize({theme: 'forest'});
    }
  </script>


  
  <!-- scripts list from theme config.yml -->
  
    <script src="/js/zepto.min.js"></script>
  


<script>
  (function(window, document, undefined) {

    var timer = null;

    function returnTop() {
      cancelAnimationFrame(timer);
      timer = requestAnimationFrame(function fn() {
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if (oTop > 0) {
          document.body.scrollTop = document.documentElement.scrollTop = oTop - 50;
          timer = requestAnimationFrame(fn);
        } else {
          cancelAnimationFrame(timer);
        }
      });
    }

    var hearts = [];
    window.requestAnimationFrame = (function() {
      return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback) {
          setTimeout(callback, 1000 / 60);
        }
    })();
    init();

    function init() {
      css(".heart{z-index:9999;width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: absolute;}.heart:after{top: -5px;}.heart:before{left: -5px;}");
      attachEvent();
      gameloop();
      addMenuEvent();
    }

    function gameloop() {
      for (var i = 0; i < hearts.length; i++) {
        if (hearts[i].alpha <= 0) {
          document.body.removeChild(hearts[i].el);
          hearts.splice(i, 1);
          continue;
        }
        hearts[i].y--;
        hearts[i].scale += 0.004;
        hearts[i].alpha -= 0.013;
        hearts[i].el.style.cssText = "left:" + hearts[i].x + "px;top:" + hearts[i].y + "px;opacity:" + hearts[i].alpha + ";transform:scale(" + hearts[i].scale + "," + hearts[i].scale + ") rotate(45deg);background:" + hearts[i].color;
      }
      requestAnimationFrame(gameloop);
    }

    /**
     * 给logo设置点击事件
     * 
     * - 回到顶部
     * - 出现爱心
     */
    function attachEvent() {
      var old = typeof window.onclick === "function" && window.onclick;
      var logo = document.getElementById("logo");
      if (logo) {
        logo.onclick = function(event) {
          returnTop();
          old && old();
          createHeart(event);
        }
      }
      
    }

    function createHeart(event) {
      var d = document.createElement("div");
      d.className = "heart";
      hearts.push({
        el: d,
        x: event.clientX - 5,
        y: event.clientY - 5,
        scale: 1,
        alpha: 1,
        color: randomColor()
      });
      document.body.appendChild(d);
    }

    function css(css) {
      var style = document.createElement("style");
      style.type = "text/css";
      try {
        style.appendChild(document.createTextNode(css));
      } catch (ex) {
        style.styleSheet.cssText = css;
      }
      document.getElementsByTagName('head')[0].appendChild(style);
    }

    function randomColor() {
      // return "rgb(" + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + ")";
      return "#F44336";
    }

    function addMenuEvent() {
      var menu = document.getElementById('menu-main-post');
      if (menu) {
        var toc = document.getElementById('toc');
        if (toc) {
          menu.onclick = function() {
            if (toc) {
              if (toc.style.display == 'block') {
                toc.style.display = 'none';
              } else {
                toc.style.display = 'block';
              }
            }
          };
        } else {
          menu.style.display = 'none';
        }
      }
    }

  })(window, document);
</script>

  



</body>
</html>
